Ruby on rails 将没有默认值的NOTNULL字段添加到填充的数据库中
我有一张桌子,就叫我的桌子吧。它是Postgresql数据库的一部分 在MyTable中有很多条目,比如说超过一百万条。我想在这个表中添加一个字段,我们称之为MyNewField。它将通过ActiveRecord迁移添加 此字段无默认值,且不可为空。其结果是,在它的迁移类中,类似这样:Ruby on rails 将没有默认值的NOTNULL字段添加到填充的数据库中,ruby-on-rails,ruby,rails-activerecord,Ruby On Rails,Ruby,Rails Activerecord,我有一张桌子,就叫我的桌子吧。它是Postgresql数据库的一部分 在MyTable中有很多条目,比如说超过一百万条。我想在这个表中添加一个字段,我们称之为MyNewField。它将通过ActiveRecord迁移添加 此字段无默认值,且不可为空。其结果是,在它的迁移类中,类似这样: class AddMyFieldToMyTable < ActiveRecord::Migration def change add_column :my_table, :my_field, :
class AddMyFieldToMyTable < ActiveRecord::Migration
def change
add_column :my_table, :my_field, :text, null: false
end
end
但是,它将触发错误PG::NotNullViolation,因为该表已包含行,所有行的MyField都将设置为NULL
我想做的是:添加不带默认值的行,并将null设置为false,而不触发PG::notnull冲突。然后,在每个记录中插入另一个表中的值
这可能是通过添加设置为true的nullable字段,然后添加值,然后将其更改回设置为false的nullable来实现的。但是,我想知道是否可以在一次快照中执行此操作。您必须确保另一个表中的每个项目都有my_字段值
class AddMyFieldToMyTable < ActiveRecord::Migration
def up
add_column :my_table, :my_field, :text
execute("insert into my_table(my_field) values (select my_field from different_table where my_table.id = different_table.different_id)")
change_column :my_table, :my_field, :text, null: false
end
def down
remove_column :my_table, :my_field
end
end
所有迹象似乎都表明,这不可能一蹴而就;您必须添加不带null约束的列,填充数据,然后添加null约束
class AddMyFieldToMyTable < ActiveRecord::Migration
def change
add_column :my_table, :my_field, :text
reversible do |dir|
dir.up do
# populate my_field col
change_column :my_table, :my_field, :text, null: false
end
end
end
end
资源:
如果您真的只想设置一次列,也许可以使用临时默认值生成它,然后立即使用实际数据更新它
class AddMyFieldToMyTable < ActiveRecord::Migration
def change
add_column :my_table, :my_field, :text, default: 'tmp', null: false
reversible do |dir|
dir.up do
# populate my_field col
end
end
end
end