在 postgresql 9.3.5 上启用和禁用约束时出错

air*_*man 2 postgresql-9.3

我有一个要求涉及在 centos6.5 机器上运行的 postgresql 9.3.5 中的批量加载数据。这个想法是在批量加载之前禁用约束,并在数据加载完成后再次启用。我禁用约束没有问题,当我尝试再次启用时会出现问题。

我用来禁用约束的 sql 命令:

alter table myTableA drop constraint myTableA_id_fkey cascade;
alter table myTableB drop constraint myTableB_id_fkey cascade;
alter table myTableC drop constraint myTableC_id_fkey cascade;
Run Code Online (Sandbox Code Playgroud)

我想用来启用约束的 sql 命令:

ALTER TABLE myTableA ADD CONSTRAINT myTableA_id_fkey;
ALTER TABLE myTableB ADD CONSTRAINT myTableB_id_fkey;
ALTER TABLE myTableC ADD CONSTRAINT myTableC_id_fkey;
Run Code Online (Sandbox Code Playgroud)

但是当我尝试启动启用约束时,我收到以下信息:

ERROR:  syntax error at or near ";"
Run Code Online (Sandbox Code Playgroud)

第 1 行:...oor_element 添加约束 myTableA_id_fkey;

来源:

我做错了什么?

另一个问题,每次使用这种方式加载数据库时都这样做是个好主意吗?这应该是每天执行一次的批量加载。

http://www.postgresql.org/docs/9.3/static/sql-altertable.html

Cra*_*ger 5

您没有启用/禁用约束。您正在删除并重新创建它们。重新创建它们时,您必须再次定义它们,因为数据库在您告诉它时丢弃了它对它们的了解。

也许您打算禁用而不是删除约束?

如果是这样:你不能那样做。没有DISABLE CONSTRAINTS选择或类似的东西。

因此,在 PostgreSQL 提供暂时禁用数据加载约束的适当方法之前,最好的方法可能是每次删除并重新创建约束。

为此,您必须使用ALTER TABLE ... ADD CONSTRAINT ...具有完整约束定义的正确、完整的命令。


(以下风险会造成无法检测和无效的 FK 违规。除非您真的非常确定需要这样做,否则不要这样做,而只是删除并重新创建上述约束。)

可以为外键约束做些什么,尽管这不是一个好主意,但是:

  • 使用以下命令禁用实现约束检查的系统触发器 ALTER TABLE ... DISABLE TRIGGER ALL
  • 做你的工作
  • 使用重新启用外键约束触发器 ALTER TABLE .. ENABLE TRIGGER ALL

请注意,这是非常严厉的,仅影响FOREIGN KEY约束(不CHECKNOT NULLEXCLUSIONPRIMARY KEYUNIQUE等约束)和一般难看。

最重要的是,这永远不会验证约束实际上是正确的,但是您可以通过额外的技巧来做到这一点:将每个约束标记为NOT VALID在目录中,然后使用VALIDATE CONSTRAINT. PostgreSQL 不提供公开且受支持的方法来将现有 FK 约束标记为NOT VALID,因此没有适当安全的方法来执行此操作。


理想情况下,PostgreSQL 将允许外键检查约束为FOR EACH STATEMENTand DEFERRABLE,因此您可以将它们推迟到提交。不过,这目前无济于事,因为他们仍然必须为每一行运行一次检查,批量进行检查并没有节省。如果 PostgreSQL 在某个时候获得对语句级触发器中已更改元组的虚拟表的支持(正如最近在 pgsql-hackers 上讨论的那样),这可能是可能的。