我需要将所有表中所有主键的列类型更改为
UUID
格式。
如何在不触发外键检查的情况下进行迁移?
我尝试了以下两件事,但仍然触发错误:
Mysql2::Error: Cannot change column 'id': used in a foreign key constraint 'fk_rails_6010a70481' of table 'project_development.some_other_table'
.
class JustAnotherMigration < ActiveRecord::Migration[7.0]
def change
ActiveRecord::Base.connection.disable_referential_integrity do
change_column :cities, :id, :uuid
end
end
end
.
class JustAnotherMigration < ActiveRecord::Migration[7.0]
def change
ActiveRecord::Base.connection.execute "SET FOREIGN_KEY_CHECKS=0;"
change_column :cities, :id, :uuid
ActiveRecord::Base.connection.execute "SET FOREIGN_KEY_CHECKS=1;"
end
end
Rails 版本:
7.0.4.3
MariaDB 版本:
11.1.2
您严重低估了更改主键类型的痛苦程度。如果您想要更改主键类型而不仅仅是更改数字类型,则必须首先实际更新所有相关表,以避免孤立这些表中的记录。
所以这里的流程基本上应该是:
cities.uiid
UUID 类型列。暂时不要触碰id
栏。other_table.city_uuid
列。它应该可以为空,您现在可以跳过外键约束。other_table.city_uuid
填充cities.uiid
。这可以通过 OtherModel.include(:city).find_each { |om| om.update(city_uuid: om.city.uiid) }
或通过使用 UPDATE ALL
和子查询来完成。other_table.city_id
列。这将解决外键约束问题。cities.id
。这可能需要您先删除索引。cities.uuid
重命名为 cities.id
。other_table.city_uuid
重命名为 other_table.city_id
,添加外键约束并将表更改为不可空(如果适用)。