我正在尝试将表主键 ID 更改为 uuid。但问题是数据已经在生产中。有一个选项可以重新编写整个迁移,但随后我们丢失了我们已有的数据。
表格之间也有太多关联。那么有没有办法处理这种情况?
为此,我们将 phoenix 和 elixir 与 postgres 结合使用。
答案 0 :(得分:0)
是的。一个人可能通过几个步骤来完成这项任务,其中一些是针对数据库执行原始 SQL。
:uuid
(正常迁移)和用唯一值填充它(使用 ecto UUID 生成器,例如)Ecto.Adapters.SQL.query/4
重新分配表中的主键¹id
到 uuid
和 then 创建引用此表的所有其他表指向 uuid
²¹ 有点类似于以下几行(未经测试)
defmodule MyRepo.Migrations.ChangeFK do
def up do
MyRepo.query("""
CREATE UNIQUE INDEX CONCURRENTLY foo_pkey_idx ON foo(id);
ALTER TABLE foos
DROP CONSTRAINT foo_pkey,
ADD CONSTRAINT foo_pkey PRIMARY KEY USING INDEX foo_pkey_idx;
""")
end
def down do
raise "unreversible"
end
end
² 有点像
defmodule MyRepo.Migrations.AlterFK do
def up do
MyRepo.query("""
ALTER TABLE bars DROP CONSTRAINT foo_pkey;
UPDATE bars SET foo_id = (SELECT uuid FROM foos WHERE id = foo_id);
ALTER TABLE bars
ADD CONSTRAINT foo_pkey
FOREIGN KEY (foo_id)
REFERENCES foos (uuid);
""")
end
def down do
raise "unreversible"
end
end