如何将ActiveRecord关系划分为连续组以更正数据?

时间:2016-09-08 14:55:57

标签: ruby-on-rails-4 activerecord

我们有一些错误的数据,我正在尝试编写data_migration来修复一些数据。有1密耳的错误记录。

将这些记录分组成组的最佳方法是什么,所以我不会一直锁定数据库?

说我有这个查询: (错误的数据)

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

1 个答案:

答案 0 :(得分:0)

一个选项可能是:

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

未经测试的代码。

您也可以在循环中进行睡眠,并提交(如果不自动发出)。它在整体效率方面并不理想,但是如果你不想让忙碌的OLTP数据库充满请求,那么它的方法也不会太糟糕。