Ruby - 将条目从CSV插入数据库

时间:2013-04-01 21:19:06

标签: ruby-on-rails ruby csv

我有一个上传的CSV文件,我这样解析:

CSV.foreach(@my_file.file.path) do |row|
    puts row[1]
end

传入的CSV文件至少包含以下列:“id”,“name”,“number”,“phone”和“food”。

我想做点什么:

CSV.foreach(@my_file.file.path) do |row|
     //find the columns in "row" associated with "id", "name", "number"
     //even though I don't know definitively which column they will be in
     //for example, "name" may be the 2nd or 3rd or 4th column (etc)

     //insert into my_table values(id, name, number)

end

请注意,CSV文件始终将列名作为第一行,但是从文件到文件,这些列的顺序可能会有所不同。

2 个答案:

答案 0 :(得分:9)

以下是一段代码,它只会将您关注的字段收集到一个哈希数组中:

require 'csv'

fields_to_insert = %w{ id name food number phone }
rows_to_insert = []

CSV.foreach("stuff.csv", headers: true) do |row|
  row_to_insert = row.to_hash.select { |k, v| fields_to_insert.include?(k) }
  rows_to_insert << row_to_insert
end

鉴于stuff.csv的以下内容:

junk1,name,junk2,food,id,junk4,number,phone
foo,Jim,bar,pizza,123,baz,9,555-1212
baz,Fred,bar,sushi,55,foo,44,555-1213

rows_to_insert将包含:

[{"name"=>"Jim",
  "food"=>"pizza",
  "id"=>"123",
  "number"=>"9",
  "phone"=>"555-1212"},
 {"name"=>"Fred",
  "food"=>"sushi",
  "id"=>"55",
  "number"=>"44",
  "phone"=>"555-1213"}]

我会接受并使用activerecord-import一次性插入所有内容:

SomeModel.import(rows_to_insert)

您可以在CSV循环中一次插入一条记录,但这样效率很低,并且由于id通常是受保护的属性,因此您无法对其进行大量分配,因此您必须这样做这要插入一条记录:

some_model = SomeModel.new(row_to_insert.select { |k, v| k != "id" }
some_model.id = row_to_insert["id"]
some_model.save!

......或类似的东西。

答案 1 :(得分:3)

如果第一行是标题名称,您可以使用:headers => true选项parse来使用第一行作为数据的键。

text = File.read(@my_file.file.path)
csv = CSV.parse(text, :headers => true)
csv.each do |row|
  row = row.to_hash.with_indifferent_access
  YourModel.create!(row.to_hash.symbolize_keys)
end