fre*_*est 195 csv import ruby-on-rails
我想将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
Run Code Online (Sandbox Code Playgroud)
你能给我一些代码来告诉我最好的方法吗,谢谢.
yfe*_*lum 364
require 'csv'
csv_text = File.read('...')
csv = CSV.parse(csv_text, :headers => true)
csv.each do |row|
Moulding.create!(row.to_hash)
end
Run Code Online (Sandbox Code Playgroud)
Tom*_*Leu 196
更简单的yfeldblum的答案,更简单,也适用于大文件:
require 'csv'
CSV.foreach(filename, :headers => true) do |row|
Moulding.create!(row.to_hash)
end
Run Code Online (Sandbox Code Playgroud)
不需要with_indifferent_access或symbolize_keys,也不需要先将文件读入字符串.
它不会立即将整个文件保存在内存中,而是逐行读取并在每行创建一个Molding.
Til*_*ilo 11
该smarter_csv宝石是专为这个用例发布:读取从CSV文件中的数据,并快速创建数据库条目.
require 'smarter_csv'
options = {}
SmarterCSV.process('input_file.csv', options) do |chunk|
chunk.each do |data_hash|
Moulding.create!( data_hash )
end
end
Run Code Online (Sandbox Code Playgroud)
您可以使用该选项一次chunk_size读取N csv-rows,然后在内部循环中使用Resque生成将创建新记录的作业,而不是立即创建它们 - 这样您就可以分散生成条目的负载多个工人.
另见:https: //github.com/tilo/smarter_csv
你可以试试Upsert:
require 'upsert' # add this to your Gemfile
require 'csv'
u = Upsert.new Moulding.connection, Moulding.table_name
CSV.foreach(file, headers: true) do |row|
selector = { name: row['name'] } # this treats "name" as the primary key and prevents the creation of duplicates by name
setter = row.to_hash
u.row selector, setter
end
Run Code Online (Sandbox Code Playgroud)
如果这是您想要的,您还可以考虑从表中删除自动增量主键并将主键设置为name. 或者,如果存在形成主键的某些属性组合,请将其用作选择器。不需要索引,它只会让它更快。
| 归档时间: |
|
| 查看次数: |
195876 次 |
| 最近记录: |