首页 > 解决方案 > 没有默认的 Rails 迁移数组

问题描述

导轨 5,Postgres 9

我有超过 1000 万条模型记录。我需要添加具有数组类型的新字段。从文档中我可以添加新的迁移

add_column :model, :new_field, :string, array: true, default: []

但是在它之后,由于许多设置默认值的 Alter 操作,数据库被阻塞了。

创建没有(默认值:[])值的新数组字段是真的吗?

标签: ruby-on-railspostgresqlmigration

解决方案


  1. 在表中添加一列,默认值为null
  2. 批量更新行(默认1000)并设置[]为值
  3. NOT NULL在列上设置

class AddCategoriesToProducts < ActiveRecord::Migration[6.0]
  disable_ddl_transaction!

  def up
    ActiveRecord::Base.transaction do
      add_column :products, :categories, :string, array: true

      execute <<~SQL
        ALTER TABLE products ALTER COLUMN categories SET DEFAULT '{}';
      SQL
    end

    Product.find_in_batches(batch_size: 1000).with_index do |products, index|
      puts "Processing #{index + 1}"
      Product.where(id: products.map(&:id)).update_all(categories: [])
    end

    ActiveRecord::Base.transaction do
      execute <<~SQL
        ALTER TABLE products ALTER COLUMN categories SET NOT NULL;
      SQL
    end
  end

  def down
    ActiveRecord::Base.transaction do
      remove_column :products, :categories
    end
  end
end

这是一个缓慢的迁移,您必须等待它完成,但它会阻止锁定表。


推荐阅读