/ / Ruby on Rails exporta para csv - mantém a ordem de instruções de seleção do mysql - mysql, ruby-on-rails, csv, mais rápidocsv

Exportação de Ruby on Rails para csv - mantenha a ordem de instruções de seleção do mysql - mysql, ruby-on-rails, csv, fastcsv

Exportando alguns dados do mysql para um arquivo csv usando o FasterCSV. Eu gostaria que as colunas no CSV emitido estivessem na mesma ordem que a instrução select na minha consulta.

Exemplo:

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

Saída CSV:

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

Quero as colunas CSV na mesma ordem que minhasinstrução select. Obviamente, o método de atributos não vai funcionar. Alguma idéia sobre a melhor maneira de garantir que as colunas no meu arquivo csv estejam na mesma ordem que a instrução select? Temos muitos dados e o desempenho é um problema. A instrução select não é estática. Eu sei que eu poderia fazer um loop através dos nomes das colunas nas linhas. Cada loop, mas parece meio sujo.

Respostas:

1 para resposta № 1

Use o Vírgula gema:

class Data < ActiveRecord:Base

comma do
name
age
height
weight
end

comma :height_weight do
name
age
height_in_feet
weight
end


end

Agora você pode gerar o CSV da seguinte maneira:

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

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

Editar:

Os localizadores ActiveRecord não suportam colunas calculadas no conjunto de resultados, ou seja,

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

Você pode usar select_extra_columns gem se você deseja incluir as colunas calculadas.


0 para resposta № 2

Tente isto:

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)