首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Rails 3/4中批量运行更新?

如何在Rails 3/4中批量运行更新?
EN

Stack Overflow用户
提问于 2014-04-24 02:48:49
回答 3查看 26.8K关注 0票数 43

我需要批量更新数千条记录,并且我希望批量处理这些更新。首先,我尝试了:

代码语言:javascript
复制
Foo.where(bar: 'bar').find_in_batches.update_all(bar: 'baz')

我希望...which能生成这样的语句:

代码语言:javascript
复制
"UPDATE foo SET bar = 'baz' where bar='bar' AND id > (whatever id is passed in by find_in_batches)"

这不起作用,因为find_in_batches返回一个数组,而update_all需要一个ActiveRecord关系。

这是我接下来尝试的:

代码语言:javascript
复制
Foo.where(bar: 'bar').select('id').find_in_batches do |foos|
  ids = foos.map(&:id)
  Foo.where(id: ids).update_all(bar: 'baz')
end

这是可行的,但显然它先运行select,然后运行update,而不是基于我的“where”条件进行单次更新。有没有办法清理这一点,这样select和update就不必是单独的查询了?

EN

回答 3

Stack Overflow用户

发布于 2016-09-22 15:32:17

在Rails5中,有一个新的方便的方法ActiveRecord::Relation#in_batches来解决这个问题:

代码语言:javascript
复制
Foo.in_batches.update_all(bar: 'baz')

有关详细信息,请查看documentation

票数 77
EN

Stack Overflow用户

发布于 2015-02-12 00:35:59

pdobb的答案是正确的,但在Rails 3.2.21中不适用于我,因为这个问题是ActiveRecord不能解析带有更新调用的偏移:

https://github.com/rails/rails/issues/10849

我相应地修改了代码,它可以很好地同时在我的Postgres表上设置默认值:

代码语言:javascript
复制
batch_size = 1000
0.step(Foo.count, batch_size).each do |offset|
  Foo.where('id > ? AND id <= ?', offset, offset + batch_size).
      order(:id).
      update_all(foo: 'bar')
end
票数 4
EN

Stack Overflow用户

发布于 2017-08-17 01:56:11

我还没有机会测试这一点,但是你也许可以使用ARel和子查询。

代码语言:javascript
复制
Foo.where(bar: 'bar').select('id').find_in_batches do |foos|
  Foo.where( Foo.arel_table[ :id ].in( foos.to_arel ) ).update_all(bar: 'baz')
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23252811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档