Как реализовать массовую вставку в Rails 3 - PullRequest
23 голосов
/ 14 декабря 2011

Мне нужно вставить массив писем в виде разных записей в мою таблицу контактов.Как это можно сделать.

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 запросов вставки.Мне просто нужно один запрос вставки, чтобы вставить эти значения.Как это можно сделать в рельсах 3.0.9 (и в идеале MySQL).Пожалуйста, помогите

Ответы [ 4 ]

50 голосов
/ 14 декабря 2011

activerecord-import реализует AR # import

activerecord-import - это библиотека для массовой вставки данных с использованием ActiveRecord.

посмотрите, как это работает:

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

Дом проекта находится на Github , и это wiki .

4 голосов
/ 05 апреля 2013

Вы также можете попробовать 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», поэтому вам не нужно проверять, существует ли запись.В вашем примере это не проблема, но в большинстве приложений она становится одной.

2 голосов
/ 18 декабря 2014

Самый простой способ без дополнительных гемов состоит в том, чтобы объединить строку и выполнить ее за одну вставку 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)
1 голос
/ 11 апреля 2013

Я только что написал небольшой патч для Active Record 3.2, чтобы ВСТАВИТЬ много новых записей одним SQL-запросом, посмотрите его:

https://github.com/alexdowad/showcase/blob/master/activerecord/bulk_db_operations.rb

...