如何在 postgresql 中禁用外键约束

Ram*_*mya 4 postgresql postgresql-9.1 postgresql-9.4 amazon-aurora aws-dms

我正在使用 AWS Aurora Postgres 并使用 DMS 从 RDS postgres 迁移到 Aurora PG。为了执行 FULL LOAD,我想在所有对象上禁用外键约束和触发器。我能够禁用触发器,但找不到禁用约束的方法。

下面不起作用:

更改表 so_items 禁用约束 so_items_so_id_fkey;

它抛出:

错误:“CONSTRAINT”第 1 行或附近的语法错误:ALTER TABLE so_items DISABLE CONSTRAINT so_items_so_id_fkey; ^ SQL 状态:42601 字符:30

在参数组中设置 "session_replication_role" = "replica" 不起作用。当 DMS 任务尝试截断准备的表部分时,它仍然因外键违规错误而失败。

请告知任何解决方法。

注意:我不能在下面做,因为在 RDS 中,即使使用主帐户我也无权这样做:

alter table so_items disable trigger ALL;
Run Code Online (Sandbox Code Playgroud)

错误:权限被拒绝:“RI_ConstraintTrigger_c_16520”是系统触发器 SQL 状态:42501

cle*_*ens 5

您不能禁用约束。这毫无意义。

您可能DROP CONSTRAINT小号

ALTER TABLE so_items DROP CONSTRAINT so_items_so_id_fkey;
Run Code Online (Sandbox Code Playgroud)

这将永久删除它,或将约束检查推迟到交易结束:

ALTER TABLE so_items ALTER CONSTRAINT so_items_so_id_fkey DEFERRABLE INITIALLY DEFERRED;
Run Code Online (Sandbox Code Playgroud)

通过该修改,在当前事务结束时的修改之后评估约束。这将允许您打破事务内部的约束。

您不应该修改 Postgres 约束所依赖的触发器。这是一个您不应该关心的实现细节。

编辑:也可以禁用触发器,这也会影响表的外键约束

ALTER TABLE so_items DISABLE TRIGGER ALL;
Run Code Online (Sandbox Code Playgroud)

但是当您之后重新启用触发器时,不会检查外键。这可能会导致数据库中的外键无效/不一致。

  • 您说这没有意义,通常情况下确实如此,但在某些情况下这很有用,例如通过迁移填充大型数据库。这个问题很可能被问到,因为 MySQL 支持这个函数 (8认同)
  • 实际上,您可以禁用约束,并且 [PostgreSQL 文档](https://www.postgresql.org/docs/8.1/sql-altertable.html) 自 8.1 (2005) 以来特别提到“禁用触发器全部”禁用系统触发器强制执行外键约束,这正是OP想要的,所以你的答案是错误的,并且误导了从搜索引擎来到这里的人们。另外,说OP不应该关心他正确诊断的问题是完全没有帮助和居高临下的。 (4认同)
  • 不仅仅是 MySQL 支持这一点。Oracle、SQL Server 也是如此。这对他们来说非常有意义。它的目的不仅仅是恢复数据库。正如凯尔指出的那样,迁移。 (2认同)
  • 当您想稍后重新启用约束时,禁用约束非常有意义。 (2认同)