我想将CSV文件中的数据导入现有的数据库表 . 我不想保存CSV文件,只需从中获取数据并将其放入现有表中 . 我正在使用Ruby 1.9.2和Rails 3 .
这是我的表:
create_table "mouldings", :force => true do |t|
t.string "suppliers_code"
t.datetime "created_at"
t.datetime "updated_at"
t.string "name"
t.integer "supplier_id"
t.decimal "length", :precision => 3, :scale => 2
t.decimal "cost", :precision => 4, :scale => 2
t.integer "width"
t.integer "depth"
end
你能给我一些代码来告诉我最好的方法吗,谢谢 .
11 回答
更简单的yfeldblum的答案,更简单,也适用于大文件:
不需要with_indifferent_access或symbolize_keys,也不需要先将文件读入字符串 .
它不会立即将整个文件保存在内存中,而是逐行读取并在每行创建一个Molding .
smarter_csv
gem是专门为此用例创建的:从CSV文件读取数据并快速创建数据库条目 .您可以使用选项
chunk_size
一次读取N csv-rows,然后在内部循环中使用Resque生成将创建新记录的作业,而不是立即创建它们 - 这样您就可以分散生成的负载多个 Worker 的条目 .另见:https://github.com/tilo/smarter_csv
这可以帮助 . 它也有代码示例:
http://csv-mapper.rubyforge.org/
或者执行相同的rake任务:
http://erikonrails.snowedin.net/?p=212
您可以尝试Upsert:
如果这是你想要的,你也可以考虑从表中删除自动增量主键并将主键设置为
name
. 或者,如果存在形成主键的某些属性组合,请将其用作选择器 . 不需要索引,只会让它更快 .最好将数据库相关进程包装在
transaction
块中 . 代码片段是将一组语言播种到语言模型的完整过程,下面的代码段是
languages.csv
文件的一部分,使用这个宝石:https://rubygems.org/gems/active_record_importer
然后你现在可以使用:
请确保您的 Headers 与表格的列名相匹配
更好的方法是将其包含在rake任务中 . 在/ lib / tasks /中创建import.rake文件,并将此代码放到该文件中 .
之后在终端中运行此命令
rake csv_model_import[file.csv,Name_of_the_Model]
我知道这是一个古老的问题,但它仍然在谷歌的前10个链接 .
逐行保存行并不是非常有效,因为它会导致循环中的数据库调用,您最好避免这种情况,特别是当您需要插入大量数据时 .
使用批量插入更好(并且速度更快) .
您可以手动构建这样的查询,而不是使用
Model.connection.execute(RAW SQL STRING)
(不推荐)或使用gemactiverecord-import
(它于2010年8月11日首次发布)在这种情况下只需将数据放入数组rows
并调用Model.import rows
refer to gem docs for details
最好使用CSV :: Table并使用
String.encode(universal_newline: true)
. 它将CRLF和CR转换为LF如果要使用SmartCSV
这表示每行
"\t"
中的制表符分隔数据,行以新行分隔"\n"