簡體   English   中英

如何使用 Arel 批量插入?

[英]How to bulk insert with Arel?

我有類似以下循環的東西,它創建了許多插入:

table = Arel::Table.new(:users)
users.each do |user|
  manager = Arel::InsertManager.new(ActiveRecord::Base)
  manager.into(table).insert([
    [table[:name], user.name],
    [table[:created_at], user.created_at],
    [table[:updated_at], user.updated_at]
  ])
  # INSERT INTO users (name) VALUES ('a')
  @conn.insert(manager.to_sql)
end

但是,我想找到一種方法來僅獲取要插入的值。 在這種情況下,我將能夠對所有值進行一次插入。

PS:請注意我不想寫 sql 字符串(安全問題)。

table = Arel::Table.new(:users)
inserts = []
users.each do |user|
  manager = Arel::InsertManager.new(ActiveRecord::Base)
  manager.into(table).insert([
    [table[:name], user.name],
    [table[:created_at], user.created_at],
    [table[:updated_at], user.updated_at]
  ])
  inserts << "(#{??manage values??})"
end
# INSERT INTO users (name) VALUES ('a'), ('b'), ('c')
@conn.insert(????)

本月早些時候出現了一個名為bulk_insert 這應該為您提供您正在尋找的功能:

Model.bulk_insert do |worker|
  worker.add(...)
  worker.add(...)
  ...
end

# Produces:
INSERT INTO models (...) VALUES
  (...),
  (...),
  (...),
  (...),
  ...

因為它是一個相當新的庫,我還沒有機會使用它,所以我不確定它的 Arel 功能。

您可以使用活動記錄導入

如果您的 AREL 版本已經支持create_tuple ,它將類似於:

        table = Table.new(:users)
        manager = Arel::InsertManager.new
        manager.into table

        manager.columns << table[:id]
        manager.columns << table[:name]

        manager.values = manager.create_tuple([
          manager.create_values(%w{ 1 david }),
          manager.create_values(%w{ 2 kirs }),
          manager.create_values(["3", Arel.sql('DEFAULT')], []),
        ])

        # INSERT INTO "users" ("id", "name") VALUES ('1', 'david'), ('2', 'kirs'), ('3', DEFAULT)
      end

取自這里: https : //github.com/kirs/arel/blob/5d6d14cb6be217abc04253da0fe49721d09e9575/test/test_insert_manager.rb#L31

查看bulk_insert (感謝@Gavin Miller),我意識到他們使用Rails cote來防止sql 注入。

因為我需要一些定制的東西,所以我不會去尋找寶石。 所以,我的最終解決方案如下,以防其他人有類似的要求:

inserts = []
users.each do |user|
  inserts << %{(
    #{@conn.quote(user.name)},
    #{@conn.quote(user.created_at)},
    #{@conn.quote(user.updated_at)}
  )}
end

sql = %{
  INSERT INTO users
  (name, created_at, updated_at)
  VALUES #{inserts.join(',')}
}

@conn.execute(sql)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM