我正在使用活动记录来获取我的故事,然后生成一个CSV,标准的方式在轨道铸造中完成。但是我有很多行,需要几分钟时间。我想如果我可以让posgresql做csv渲染,那么我可以节省一些时间。导航原始查询的CSV格式,将通过控制器返回
继承人什么,我现在所拥有的:
query = "COPY stories TO STDOUT WITH CSV HEADER;"
results = ActiveRecord::Base.connection.execute(query);
但结果是空的这个查询:
=> #<PG::Result:0x00000006ea0488 @connection=#<PG::Connection:0x00000006c62fb8 @socket_io=nil, @notice_receiver=nil, @notice_processor=nil>>
2.0.0-p247 :053 > result.count
=> 0
知道更好的办法:我怀疑
2.0.0-p247 :059 > result.to_json
=> "[]"
我控制器看起来像这样:
format.csv { send_data raw_results }
这适用于普通查询,我只是无法弄清楚SQL语法是否已将CSV结果返回给导轨。
UPDATE
得到了120000毫秒的CSV出口下降到290毫秒
我的模型:
def self.to_csv(story_ids)
csv = []
conn = ActiveRecord::Base.connection.raw_connection
conn.copy_data("COPY (SELECT * FROM stories WHERE stories.id IN (#{story_ids.join(',')})) TO STDOUT WITH (FORMAT CSV, HEADER TRUE, FORCE_QUOTE *, ESCAPE E'\\\\');") do
while row = conn.get_copy_data
csv.push(row)
end
end
csv.join("\r\n")
end
我的控制器:
send_data Story.to_csv(Story.order(:created_at).pluck(:id))
有没有办法直接从数据库发送'send_data'?我的意思是,没有将它保存到'csv'数组中? –
@FernandoFabreti听起来像copy_data函数返回的行需要连接在一起成为一个文件。如果没有某种变量赋值,我不认为它们是组合这些行的方式。你可以从头开始使用一个字符串,然后在循环中追加。会对性能差异感兴趣。 – penner
我不得不将'csv.join(“\ r \ n”)'改为'csv.join(“\ n”)'使它正确地产生行。它最初增加了一个额外的换行符。不知道这是否会影响其他非* nix机器... – allthesignals