2010-03-25 4 views
0

Exporter des données de mysql vers un fichier csv en utilisant FasterCSV. J'aimerais que les colonnes du fichier CSV généré soient dans le même ordre que l'instruction select dans ma requête.Ruby on Rails exporter vers csv - maintenir l'ordre de sélection de l'instruction mysql

Exemple:

rows = Data.find(
    :all, 
    :select=>'name, age, height, weight' 
) 

headers = rows[0].attributes.keys 
FasterCSV.generate do |csv| 
    csv << headers 
    rows.each do |r| 
    csv << r.attributes.values 
    end 
end 

CSV Sortie:

height,weight,name,age 
74,212,bob,23 
70,201,fred,24 
. 
. 
. 

Je veux les colonnes CSV dans le même ordre que mon instruction select. Évidemment, la méthode des attributs ne va pas fonctionner. Des idées sur la meilleure façon de s'assurer que les colonnes de mon fichier csv seront dans le même ordre que l'instruction select? Vous avez beaucoup de données et la performance est un problème. L'instruction select n'est pas statique. Je me rends compte que je pourrais faire une boucle sur les noms de colonnes dans la boucle rows.each, mais ça semble un peu sale.

Répondre

1

Utilisez la pierre précieuse Comma:

class Data < ActiveRecord:Base 

    comma do 
    name 
    age 
    height 
    weight 
    end 

    comma :height_weight do 
    name 
    age 
    height_in_feet 
    weight 
end 


end 

Maintenant, vous pouvez générer le CSV comme suit:

Data.all(:select => 'name, age, height, weight').to_comma 

Data.all(:select => 'name, age, height_in_feet, weight').to_comma(:height_weight) 

Edit:

Les viseurs ActiveRecord ne supporte pas les colonnes calculées dans le resultset, ie

data = Data.first(:select => 'name, age, height/12 as height_in_feet, weight') 
data.height_in_feet # throws error 

Vous pouvez utiliser la gemme select_extra_columns si vous souhaitez inclure les colonnes calculées.

+0

Merci, je vais étudier cela. J'aurais probablement dû le mentionner, mais mon instruction select est générée dynamiquement, donc je ne suis pas sûr que cela fonctionnera. Par exemple ma déclaration select pourrait être quelque chose comme «nom, âge, taille/12 comme height_in_feet, weight». – user301410

+0

Vous pouvez ajouter plusieurs sections de virgule pour votre combinaison de sélection. J'ai modifié ma réponse pour inclure des informations supplémentaires à ce sujet. –

+0

Je n'arrive pas à reproduire l'erreur dont vous parlez dans votre édition. Quelle version de rails utilisez-vous et quelle est l'erreur spécifique? – rwilliams

0

Essayez ceci:

def export_to_csv (rows, col_names) 
    col_names = col_names.split(",") if col_names.is_a?(String) 
    FasterCSV.generate do |csv| 
    # header row 
    csv << col_names 

    # data rows 
    rows.each do |row| 
     csv << col_names.collect{|name| row.send(name)} 
    end 
    end 
end 

cols = 'name, age, height, weight' 
rows = Data.find(:all, :select=> cols) 
csv = export_to_csv(rows, cols)