在rake任务中更新大量数据

时间:2015-05-12 07:56:23

标签: ruby-on-rails ruby postgresql rake-task

我有一个名为PageDensity的模型,它有大约5米的行。

当我创建项目PageDensity表时,在density coulmn中存储了5位小数精度的浮点数。

现在需求已更改为将其四舍五入到小数点后两位。

我只是编写了一个任务来围绕所有densities,但它会让系统变得如此沉重而且卡住了。即使我无法使用query,因为我的舍入方式会发生变化,例如0.57500将四舍五入为0.57,而0.57600将四舍五入为0.58

到目前为止我所尝试的只是:

  task round_densities: :environment do
    application_object = ApplicationController.new
    time = Benchmark.realtime do
      ActiveRecord::Base.transaction do
        PageDensity.all.each {|p| p.update_attributes(density: application_object.round_number(p.density))}
      end
    end
    puts '***************************************'
    puts "Total Time Consumed #{time} seconds"
    puts '***************************************'
  end

我也尝试查询舍入但失败了:

select round(0.00500, 2)
#this returns 0.01 as this should return 0.00

我正在使用postgres任何想法来psql query或使用rails

2 个答案:

答案 0 :(得分:2)

您应该使用批次进行更改

PageDensity.all.each

使用:

PageDensity.all.find_each

检查doc

但要这样做,你必须删除实际上无用的交易。

Sideremark,如果你没有要回拨的回调,请替换:

p.update_attributes(density: application_object.round_number(p.density))

使用:

p.update_column(:density, application_object.round_number(p.density))

这将节省一些额外的时间。

答案 1 :(得分:2)

听起来你的舍入要求只是正常舍入的0.001。

在这种情况下,我认为你可以运行sql update:

update page_densities set density = round(density - 0.001, 2)

这将是这样的:

0.011 => round(0.010, 2) => 0.01
0.015 => round(0.014, 2) => 0.01
0.016 => round(0.015, 2) => 0.02
0.02  => round(0.019, 2) => 0.02