如何在Rails3中快速将对象数组保存到数据库?

时间:2011-07-27 07:37:33

标签: database ruby-on-rails-3 activerecord

我从CSV文件中读取了一大堆对象,并希望将其保存到数据库中。 这就是我在做的事情:

# Read CSV
... each do |values|
  new_value = Model.new
  ... # fill properties
  @new_values.push new_value # put it into the array
end

# now save them to the database
@new_values.each do |new_value| 
    new_value.save :validate => false
    @added_counter += 1
end

但这确实很慢,因为它会为数组中的每个元素生成一个语句。如何以快速和正确的方式完成这项工作?

2 个答案:

答案 0 :(得分:3)

也许activerecord-import可能对您有用。

它允许执行以下操作:

books = []
10.times do |i| 
  books << Book.new(:name => "book #{i}")
end
Book.import books

答案 1 :(得分:0)

这是一个基于 mu太短的评论的解决方案(谢谢!)。 我使用手工制作的SQL语句并执行它。

  insert_statement = "INSERT INTO table_name (custom_property_from_parameter"
  # the properties from the model are fetched by a method, to keep it a little bit generic, loop trough them and give their names to the statement
  Model.parameter_names.each do |parameter|
    insert_statement += "," + parameter
  end
  insert_statement += ") VALUES "
  @new_values.each do |new_value|
    insert_statement += "(" + params[:custom_property]
    Model.parameter_names.each do |parameter|
      # Rails' nil has to be converted into NULL for SQL
      if nil == new_value.send(parameter)
        insert_statement += ",NULL"
      else
        insert_statement += "," + new_value.send(parameter).to_s
      end
    end
    insert_statement += "),"
    @added_counter += 1
  end
  # Remove the last , with ;
  insert_statement = insert_statement[0..-2]
  insert_statement += ";"
  # now execute the statement
  ActiveRecord::Base.connection.execute insert_statement

此解决方案大约需要三分之一的时间。但这对我来说似乎有点像黑客。