【问题标题】:Disable ALL checks on foreign keys when migrating Postgresql迁移 Postgresql 时禁用对外键的所有检查
【发布时间】:2020-09-29 17:28:50
【问题描述】:

在过去的几天里,我已经从 MySQL 迁移到 Postgres。但没有任何成功。我现在已经将我的 MySQL 数据库移植到 Postgres,但我在 VARCHAR 中使用 MySQL 中的 UUID。现在我想去 postgres,但我似乎不可能将 postgres 中的 varchar 转移到 UUID。因为数据库不是空的,所以存在外键约束。我想我可以通过以下方式将它们全部关闭:

set session_replication_role to replica;

我还尝试关闭表的所有触发器。例如,这是我尝试运行的查询:

ALTER TABLE building_block_buildingblock DISABLE TRIGGER ALL;
ALTER TABLE building_block_buildingblockhistory DISABLE TRIGGER ALL;
ALTER TABLE building_block_buildingblockhistory ALTER COLUMN id SET DATA TYPE UUID USING (uuid_generate_v4());
ALTER TABLE building_block_buildingblock ALTER COLUMN id SET DATA TYPE UUID USING (uuid_generate_v4());
ALTER TABLE building_block_buildingblockhistory ALTER column building_block_id SET DATA TYPE UUID USING (uuid_generate_v4());

但我得到了错误:

SQL Error [42804]: ERROR: foreign key constraint "building_block_buildingbl_building_block_id_e08cbc73_fk" cannot be implemented
  Detail: Key columns "building_block_id" and "id" are of incompatible types: character varying and uuid.

我还尝试将其包装在一个函数中,如下所示:PostgreSQL - disabling constraints

这是我试过的功能:

CREATE OR REPLACE FUNCTION f() RETURNS void AS
$BODY$
begin
set session_replication_role to replica;
SET CONSTRAINTS ALL deferred;
ALTER TABLE building_block_buildingblock DISABLE TRIGGER ALL;
ALTER TABLE building_block_buildingblockhistory DISABLE TRIGGER ALL;
ALTER TABLE building_block_buildingblockhistory ALTER COLUMN id SET DATA TYPE UUID USING (uuid_generate_v4());
ALTER TABLE building_block_buildingblock ALTER COLUMN id SET DATA TYPE UUID USING (uuid_generate_v4());
ALTER TABLE building_block_buildingblockhistory ALTER column building_block_id SET DATA TYPE UUID USING (uuid_generate_v4());
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
  
select f();

有没有办法进行我想做的这种迁移?我现在唯一能想到的就是手动调整我的 SQL 转储文件。但这听起来不仅工作量很大,而且容易出错。

【问题讨论】:

  • 您发布的语句更改了列类型,它们不会禁用任何约束
  • 这能回答你的问题吗? PostgreSQL - disabling constraints
  • 我更新了我的答案。它似乎没有帮助

标签: sql postgresql


【解决方案1】:

以下肯定会禁用所有外键:

SET session_replication_role TO replica;

它只能作为超级用户运行。

有一个例外:您使用的触发器

ALTER TABLE ... ENABLE REPLICA|ALWAYS TRIGGER ...

即使 session_replication_role 设置为 replica 也会触发。

【讨论】:

  • 查看问题。我已经试过了。它没有用。我确实有超级用户访问权限。
  • 那你没试过。使用 SET 只会更改当前数据库会话中的设置。
  • 我用我尝试过的功能更新了我的问题。我知道它仅适用于当前的数据库会话。这就是我觉得奇怪的地方。
  • 只要您在与违反外键的操作相同的数据库会话中调用该函数,就可以正常工作。无需在某些表上显式禁用触发器。实际上,有一个警告 - 请参阅我的更新答案。
  • 如果你愿意,我可以把我的数据库发给你吗?我将删除所有敏感数据。如果您没有时间,我理解
猜你喜欢
  • 2016-11-01
  • 2016-03-21
  • 2012-06-03
  • 2019-10-27
  • 2016-06-17
  • 2016-03-23
  • 2012-07-23
  • 1970-01-01
  • 2019-08-22
相关资源
最近更新 更多