【问题标题】:How to partition an ActiveRecord relation into sequential groups for correcting data?如何将 ActiveRecord 关系划分为顺序组以更正数据?
【发布时间】:2016-09-08 14:55:56
【问题描述】:

我们有一些错误的数据,我正在尝试编写一个 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

【问题讨论】:

    标签: ruby-on-rails-4 activerecord


    【解决方案1】:

    一个选项可能是:

    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 数据库充满请求,那么这种方法还不错。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多