代码之家  ›  专栏  ›  技术社区  ›  ROBERT RICHARDSON

为什么VALIDATE约束找不到这个外键冲突?

  •  1
  • ROBERT RICHARDSON  · 技术社区  · 6 年前

    我不明白VALIDATE CONSTRAINT应该做什么。我正在转换一个数据库,以便在即将到来的公司旗舰软件产品的重大升级中使用。过去的开发人员很懒,不必费心指定外键应该放在哪里。对于我们产品的新版本,将指定并实施适当的外键。

    所以,我想将数据导入我的新数据库,然后确保没有外键冲突。在与事务的开始和结束以及处理循环键和以惊人的速度无处可去做斗争之后,我决定只禁用所有表上的所有触发器(这将禁用PostgreSQL中的外键约束检查,因为它们在幕后使用触发器),导入我的数据,重新启用触发器,然后发出VALIDATE CONSTRAINT命令。但是,在我的小测试脚本中,验证没有发现任何约束冲突。为什么不呢?

    DROP TABLE IF EXISTS base_types_minimum;
    DROP TABLE IF EXISTS gas_types_minimum;
    CREATE TABLE public.gas_types_minimum
    (
        gas_type character varying(32) COLLATE pg_catalog."default",
        CONSTRAINT gas_type_minimum_pkey PRIMARY KEY (gas_type)
    );
    
    CREATE TABLE public.base_types_minimum
    (
        base_type character varying(32) COLLATE pg_catalog."default" NOT NULL,
        gas_type character varying(32) COLLATE pg_catalog."default",
        CONSTRAINT base_type_minimum_pkey PRIMARY KEY (base_type),
        CONSTRAINT base_type_minimum_gas_type_minimum_fk FOREIGN KEY (gas_type)
            REFERENCES public.gas_types_minimum (gas_type) MATCH SIMPLE
            ON UPDATE NO ACTION
            ON DELETE NO ACTION
    );
    
    alter table base_types_minimum disable trigger all;
    insert into base_types_minimum values ('Hydrogen', 'H2');
    alter table base_types_minimum enable trigger all;
    
    alter table base_types_minimum validate constraint base_type_minimum_gas_type_minimum_fk;
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Laurenz Albe    6 年前

    原因是外键约束已标记为有效,因此未选中它。

    VALIDATE CONSTRAINT 仅适用于 作为 NOT VALID

    通过禁用触发器,您有效地破坏了完整性,并且无法恢复。这就是为什么只有当您是超级用户时才能禁用实现外键的触发器(这些触发器应该知道它们在做什么)。

    最好的做法是删除已断开的外键约束。

    有一个-不支持!–如何将约束标记为无效:

    UPDATE pg_catalog.pg_constraint
    SET convalidated = FALSE
    WHERE conname = 'base_type_minimum_gas_type_minimum_fk';