如何将ActiveRecord关系划分为顺序组以更正数据



我们有一些错误的数据,我正试图写一个data_migration来修复一些数据。有大约100万份错误记录。

什么是最好的方法来划分这些记录到组,这样我就不会锁定数据库的整个时间?

假设我有这样一个查询:(错误的数据)

apples = Apple.where(seed: "rotten")

假设我想以5000个批次更新这些apples。我该怎么做呢?

现在我有这样的东西…但这很奇怪。我怎么做第一个5000,然后下一个5000,直到没有更多的记录?为了复杂起见,我们假设有1,104,000条记录,现在有1,105,000条记录,用于一个漂亮的非整数。

这是我目前的解决方案:

class ChangeApples < ActiveRecord::Migration
  def self.up
    disable_ddl_transaction!
    batch_separator = 20
    apples = Apple.where(core:"rotten")
    (0...batch_separator).each do |modulo|
      batch = apples.where("id % #{batch_separator} = #{modulo}")
      Rails.logger.info("Updating #{batch.count} apples with ids: #{batch.pluck(:id)}.")
      batch.update_all(eventable_type: "Edible")
    end
  end
  def self.down
    raise ActiveRecord::IrreversibleMigration
  end
end

一个选项可能是:

batch_separator = 5000
batches         = 0
while Apple.where(core:"rotten").
            limit(batch_separator).
            update_all(eventable_type: "Edible") > 0 do
  puts "Updating batch #{batches += 1}"
end

未测试的代码。

您还可以在循环中放置一个sleep和一个commit(如果不是自动发出的话)。就整体效率而言,它并不理想,但如果您不想让繁忙的OLTP数据库充斥着请求,那么它是一个不错的方法。

最新更新