【问题标题】:How to do rails migrations on existing records (historical data)?如何对现有记录(历史数据)进行 Rails 迁移?
【发布时间】:2017-06-20 11:50:38
【问题描述】:

我有一个模型 (Model_A) 有两列(Column_A 和 Column_B)

我的模型里面有下面的方法,两个根据column_A生成column_B的值

Class Model_A < ActiveRecord::Base
  before_save :set_column_B

  def set_column_B
      self.column_B = get_value_from_column_A
  end

  def get_value_from_column_A
    # manipulate data from A to get value
    column_A.join(,) 
  end

end

我知道我必须创建一个新的 column_B 作为迁移的第一步,但是如何更改数据库中所有预先存在的记录以在 column_B 中具有正确的值? 我应该为此编写脚本或 Rake 任务,还是有办法通过迁移来完成?

【问题讨论】:

    标签: ruby-on-rails ruby rails-activerecord rails-migrations


    【解决方案1】:

    如果您有很多记录,则循环遍历所有记录是个坏主意。假设您有 200 万条记录,如果您采用 ActiveRecord 方式,更新列然后执行回调和验证将需要很长时间。

    如果你可以使用 SQL 本身来完成,你可以使用 SQL 方式更新所有记录

    类似于 Spree 的这种迁移

    class UpdateNameFieldsOnSpreeCreditCards < ActiveRecord::Migration
      def up
        if ActiveRecord::Base.connection.adapter_name.downcase.include? "mysql"
          execute "UPDATE spree_credit_cards SET name = CONCAT(first_name, ' ', last_name)"
        else
          execute "UPDATE spree_credit_cards SET name = first_name || ' ' || last_name"
        end
      end
    
      def down
        execute "UPDATE spree_credit_cards SET name = NULL"
      end
    end
    

    【讨论】:

    • 在这种情况下,我没有使用模型中的方法来生成值。这似乎更像是添加一个默认值?
    • 你在那个方法中到底在做什么?如果它像连接、乘法、加法或我们可以使用 SQL 实现的东西,你可以使用 raw update all
    • 你的columnA是Array数据类型吗?
    • Column_A 是文本类型。我正在使用序列化来存储格式的哈希,“sample”:[ {“name”:“A”,“value”:[“string1”,“string2”] }]。我正在尝试解析此哈希并基于它返回一个字符串。
    【解决方案2】:

    在迁移中,您可以执行以下操作:

     class AddColummBToModelA < ActiveRecord::Migration
      def up
        unless column_exists? :budgets, :column_b
          add_column :budgets, :column_b ......
          ModelA.find_each {|x| x.save! }
        end
    
      end
    
      def down
       remove_column :budgets, :column_b if column_exists? :budgets, :column_b
      end
    end
    

    【讨论】:

    • 你可能想把它改成ModelA.all.find_each {|x| x.save! }
    • 哦,是的,这样会更有效率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 2018-06-15
    • 2015-03-08
    • 2021-08-16
    • 1970-01-01
    • 2014-01-03
    相关资源
    最近更新 更多