错误启用和禁用postgresql 9.3.5上的约束

时间:2015-01-20 10:39:17

标签: 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;

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

来源:

我做错了什么?

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

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

1 个答案:

答案 0 :(得分:3)

您不能启用/禁用约束。您正在放弃并重新创建它们。重新创建它们时,您必须再次定义它们,因为数据库在您告知它时会丢弃它们的知识。

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

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

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

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


(以下风险造成无法检测到的无效FK违规行为。除非您真的确实需要,否则不要这样做,而只是删除并重新创建上述限制。)

可以为外键约束做些什么,虽然它不是一个好主意,但是:

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

请注意,这非常严厉,只会影响FOREIGN KEY个约束(不是CHECKNOT NULLEXCLUSIONPRIMARY KEY,{{1}等约束)并且通常是丑陋的。

最重要的是,这永远不会验证约束实际上是否正确,但您可以通过额外的hack来执行此操作:在目录中将每个约束标记为UNIQUE,然后使用NOT VALID重新验证它。 PostgreSQL没有提供公开和支持的方式将现有的FK约束标记为VALIDATE CONSTRAINT,因此没有正确安全的方法来执行此操作。


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