代码之家  ›  专栏  ›  技术社区  ›  aarona

Rails迁移批量更新change_column_default

  •  0
  • aarona  · 技术社区  · 6 月前

    我创建了一个进行两次默认值更新的迁移。它看起来像这样:

    class ChangeTableNameDefaultValues < ActiveRecord::Migration[7.2]
      def change
        change_column_default(:table_name, :column_1, from: 'old_default_value', to: 'new_default_value')
        change_column_default(:table_name, :column_2, from: 'old_default_value', to: 'new_default_value')
      end
    end
    

    我的门楣建议我用 change_table bulk: true 声明,所以我这样尝试:

    class ChangeTableNameDefaultValues < ActiveRecord::Migration[7.2]
      def change
        change_table :table_name, bulk: true do |t|
          # Notice here that I don't use the t variable being passed
          # to the block. I'm wondering if I need to call a method on t?
          change_column_default(:table_name, :column_1, from: 'old_default_value', to: 'new_default_value')
          change_column_default(:table_name, :column_2, from: 'old_default_value', to: 'new_default_value')
        end
      end
    end
    

    但是,在运行迁移后,我得到了以下输出:

    Migrating to ChangeTableNameDefaultValues (20250221054551)
    == 20250221054551 ChangeTableNameDefaultValues: migrating ======================
    -- change_table(:table_name, {:bulk=>true})
    -- change_column_default(:table_name, :column_1, {:from=>"old_default_value", :to=>"new_default_value"})
      TRANSACTION (0.0ms)  BEGIN
       (2.4ms)  ALTER TABLE "table_name" ALTER COLUMN "column_1" SET DEFAULT 'new_default_value'
       -> 0.0046s
    -- change_column_default(:table_name, :column_2, {:from=>"old_default_value", :to=>"new_default_value"})
       (0.5ms)  ALTER TABLE "table_name" ALTER COLUMN "column_2" SET DEFAULT 'new_default_value'
       -> 0.0017s
       -> 0.0072s
    == 20250221054551 ChangeTableNameDefaultValues: migrated (0.0072s) =============
    

    因此,它没有利用批量表更新。我想知道更改列的默认值是否可行?

    1 回复  |  直到 6 月前
        1
  •  2
  •   dbugger    6 月前

    问题是你需要使用 change_default 而不是 change_column_default .

    change_default 在中使用表的上下文 change_table 块,而 change_column_default 将表作为显式参数并生成自己的语句。

    所以有点像。。。

      def change
        change_table :table_name, bulk: true do |t|
          # No table needed, already available in context
          t.change_default(:column_1, from: 'old_default_value', to: 'new_default_value')
          t.change_default(:column_2, from: 'old_default_value', to: 'new_default_value')
        end
      end
    

    请注意,这是不可逆的。

    中可用的方法列表 change_table here .