如何在 Active Record 中检索用于批量插入的已创建 ID 列表?

Daw*_*een 6 mysql activerecord ruby-on-rails insert has-many

我有三个模型:

class Coupon < ActiveRecord::Base
  belongs_to :event
  has_many :coupon_events, :dependent => :destroy
  has_many :events, :through => :coupon_events
end 

class Event < ActiveRecord::Base
  belongs_to :event
  has_many :coupon_events, :dependent => :destroy
  has_many :coupons, :through => :coupon_events
end

class CouponEvent < ActiveRecord::Base
  belongs_to :coupon
  belongs_to :event
end
Run Code Online (Sandbox Code Playgroud)

我通读了一个 CSV 文件来创建优惠券和coupon_events。这是非常低效的,因为一次创建一个记录并导致多个查询,每个查询包括两个插入语句。

我想使用这样的单个插入查询:

coupon_string = " ('abc','AAA'), ('123','BBB')"
Coupon.connection.insert("INSERT INTO coupons (code, name) VALUES"+coupon_string)
Run Code Online (Sandbox Code Playgroud)

然后我需要为 CouponEvent 模型创建第二个插入查询,但我需要一个返回的coupon_ids 的列表。是否有内置方法可以在插入时检索 ID?

ror*_*rra -2

如果您使用 mysql 并且没有在另一个脚本/进程中插入更多行,则可以使用 last_insert_id() 获取插入的第一行的 id

    first_id = ActiveRecord::Base.connection.execute("select last_insert_id()").first[0]
Run Code Online (Sandbox Code Playgroud)

然后依次生成其他记录的id。

IE

    data = %w(one two three)
    to_insert = "('" + data.join("'), ('") + "')"
    Model.connection.insert("INSERT INTO models(name) VALUES #{to_insert}")
    first_id = ActiveRecord::Base.connection.execute("select last_insert_id()").first[0].to_i
    hash = {}
    data.each_with_index {|d, i| hash[first_id + i] = d}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个糟糕的通用解决方案,因为它依赖于生成顺序 ID 的数据库。虽然数据库经常这样做,但如果有其他用户插入同一个表,它们就不会这样做。锁定表只会降低性能,我假设您首先使用批量导入来提高性能。此外,还有其他原因导致数据库可能无法生成连续的 id,例如 id 分区(按范围,其中分配给每个数据库的 id 范围不一定相邻或什至递增,也可以按偶数/奇数) (2认同)