How can I run updates in batches in Rails 3/4?

后端 未结 6 1077
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-05 01:09

I need to mass-update many thousands of records, and I would like to process the updates in batches. First, I tried:

Foo.where(bar: \'bar\').find_in_batches.upda         


        
6条回答
  •  -上瘾入骨i
    2021-02-05 02:00

    I'm surprised, too, that there isn't an easier way to do this... but I did come up with this approach:

    batch_size = 1000
    0.step(Foo.count, batch_size).each do |offset|
      Foo.where(bar: 'bar').order(:id)
                           .offset(offset)
                           .limit(batch_size)
                           .update_all(bar: 'baz')
    end
    

    Basically this will:

    1. Create an array of offsets between 0 and Foo.count stepping by batch_size each time. For example, if Foo.count == 10500 you'd get: [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
    2. Loop through these numbers and use them as an OFFSET in the SQL query, being sure to order by id, and limiting to the batch_size.
    3. Update at most batch_size records whose "index" is greater than offset.

    This is basically the manual way to perform what you said you were hoping for in the generated SQL. Too bad it can't just be done this way already by a standard library method... though I'm sure you could create one of your own.

提交回复
热议问题