gem bulk_insert: nil:NilClass 的未定义方法“result_sets”?

gem bulk_insert: undefined method `result_sets' for nil:NilClass?

我是第一次使用 gem bulk_insert: https://github.com/jamis/bulk_insert

我成功地使用 gem 将记录从一个 table 批量复制到另一个。后来,我需要报告新记录的数量。无论如何,我看不到从 bulk_insert 返回行计数,所以我转向 return_primary_keysresult_sets 来获取计数,如自述文件中所示。

我在第 3 行添加了 inserted = 并在下面添加了最后一行:

columns = %i[first_name, last_name, email, referal]

inserted = User.bulk_insert(*columns, ignore: true, return_primary_keys: true) do |bulk|
  bulk.set_size = BATCH_SIZE

  registrants.select(:fname, :lname, :email).find_in_batches(batch_size: BATCH_SIZE) do |batch|
    batch.each do |reg|
      bulk.add [reg.fname, reg.lname, reg.email, 'self-registered']
    end
  end
end

puts "added #{inserted.result_sets.count} self-registered users"

现在,我在 puts 行上得到 NoMethodError: undefined method 'result_sets' for nil:NilClass

Readme 看了好几遍,查找问题无果。还检查了我是否有最新版本 - 1.7.0

我错过了什么?我怎样才能到达 result_sets?或者更好的是,我可以在不检索整个新主键列表的情况下获得记录数吗?

根据this issue on the repo,您需要先创建一个bulk_insert worker。所以,在你的情况下,我认为它看起来像这样:

columns = %i[first_name, last_name, email, referal]

insert_worker = User.bulk_insert(*columns, ignore: true, return_primary_keys: true)

insert_worker.set_size = BATCH_SIZE

registrants.select(:fname, :lname, :email).find_in_batches(batch_size: BATCH_SIZE) do |batch|
  batch.each do |reg|
    insert_worker.add [reg.fname, reg.lname, reg.email, 'self-registered']
  end
end

puts "added #{insert_worker.result_sets.count} self-registered users"

我在 https://github.com/jamis/bulk_insert/issues/35 中找到了答案,感谢 butnaruandrei。我必须先创建 bulk_insert 对象,然后再调用 .add() ......而不是将一个块传递给 bulk_insert with .add() within.

重要提示:我还必须在所有添加之后添加 inserter.save!。没有这个,最后的半批永远不会被保存......当传递一个块时它确实被保存了。一开始这并不明显,因为一切似乎都在工作.. .但是最后几条记录没有保存。

这段代码可以正常工作:

columns = %i[first_name, last_name, email, referal]

inserter = User.bulk_insert(*columns, ignore: true, return_primary_keys: true) 
inserter.set_size = BATCH_SIZE

registrants.select(:fname, :lname, :email).find_in_batches(batch_size: BATCH_SIZE) do |batch|
  batch.each do |reg|
    inserter.add [reg.fname, reg.lname, reg.email, 'self-registered']
  end
end

inserter.save!
count = inserter.result_sets.map(&:rows).flatten.count

puts "added #{count} self-registered users"