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

error enabling and disabling constraints on postgresql 9.3.5

我有一个要求涉及在 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;

我想用来启用约束的 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;

但是当我尝试启动启用约束时,我收到了这个:

ERROR:  syntax error at or near ";"

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

来源:

我做错了什么?

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

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

你不是 enabling/disabling 约束。您正在删除并重新创建它们。当重新创建它们时,您必须再次定义它们,因为数据库在您告诉它时会丢弃它对它们的了解。

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

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

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

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


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

对于外键约束,您可以做的事情是:

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

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

最重要的是,这永远不会验证约束是否确实正确,但您可以使用额外的 hack 来验证:在目录中将每个约束标记为 NOT VALID,然后使用 [=21= 重新验证它]. PostgreSQL 不提供 public 和支持的方法来将现有的 FK 约束标记为 NOT VALID,因此没有适当安全的方法来执行此操作。


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