在Rails 5中使用bulk_import时触发before回调



我想插入数以百万计的数据,没有一个选项来击中数据库的许多次,而不是使用这个gem做批量插入,但正如它所说,它只是做批量插入,没有内存中的Activerecord对象,它不能运行之前和之后保存回调。

所以,为了做到这一点,我写了一个代码来手动触发before_callback。

valid_books = []
invalid_books = []
books.each do |book|
if book.valid?
valid_books << book
else
invalid_books << book
end
end
valid_books.each do |book|
book.run_callbacks(:save) { false }
book.run_callbacks(:create) { false }
end
Book.import valid_books, validate: false

引用自gem文档本身。现在,在导入数据后,如何在回调后运行。谢谢你!

当我们有beforeafter回调时,bulk_import是没有用的。

您将不得不为每个插入的记录调用after_callback,或者使用.create,它将接受批量数据。

Ex: Model.create({{...}, {...}, {...} ...})

我建议你在后台作业中创建记录:

Job1

  1. batch_import设置ActiveJob
  2. 将数据解析为JSON。Ex -data_hash: {{...}, {...}, {...} ...}
  3. 批量拆分数据并循环通过每个批次
  4. 呼叫Job2(batch_data)

Job2

  1. batch_create设置ActiveJob
  2. DB.Transaction
  3. DoModel.create(batch_data)
  4. begin..rescue..ensure块内包装以上步骤

:

  • 你会有validations&callbacks按预期调用
  • 让多个worker在后台完成创建记录的任务
  • 你可以在rescue block中设置异常跟踪器来通知错误

建议:

  • 如果您正在使用PostgresDB,那么我建议使用Que
  • 广泛使用的队列是resque,Redis支持
  • 异常管理和
  • Errbit
  • 跟踪异常的气闸

如果你使用的是Postgres,你可以在回调后的导入步骤中添加这个:

Book.import valid_books, validate: false
valid_books.each do |book|
book.run_callbacks(:save) { true }
book.run_callbacks(:create) { true }
end

最新更新