如何在Rails 3中实现批量插入
我需要将一组电子邮件作为不同的记录插入到我的联系人表中。 如何才能做到这一点。
Eg: @email = ["a@b.com", "c@d.com", "e@f.com", ... ]
我不想用。
@email.each do |email| @contact = Contact.new @contact.email = email @contact.save end
这导致n插入quires。 我只需要一个插入查询来插入这些值。 如何在rails 3.0.9(以及理想的MySQL)中完成。 请帮忙
activerecord-import实现AR#import
activerecord-import是一个使用ActiveRecord批量插入数据的库。
看看它怎么运作:
books = [] 10.times do |i| books << Book.new(:name => "book #{i}") end Book.import books
Project的主页位于Github ,它是wiki 。
您也可以尝试upsert
,这几乎和activerecord-import
一样快,但只适用于(当前)MySQL,Postgres和SQLite3:
require 'upsert' Upsert.batch(Contact.connection, Contact.table_name) do |upsert| emails.each do |email| upsert.row(email: email) end end
请注意,这涉及每个记录一个数据库查询,但它是一个“upsert”,因此您不必检查记录是否已存在。 在您的示例中,这不是一个问题,但在大多数应用程序中,它最终成为一个问题。
没有额外gem的最简单方法是连接一个字符串并在一次SQL插入中执行它( http://www.electrictoolbox.com/mysql-insert-multiple-records/ )。
@email = ["a@b.com", "c@d.com", "e@f.com"] time = Time.current.to_s(:db) values = @email.map do |email| "('#{email}', '#{time}', '#{time}')" end sql = "INSERT INTO contacts (email, created_at, updated_at) VALUES #{values.join(', ')}" Contact.connection.execute(sql)
我刚刚为Active Record 3.2编写了一个小小的补丁,用一个SQL查询来插入许多新记录,检查出来:
https://github.com/alexdowad/showcase/blob/master/activerecord/bulk_db_operations.rb