当重复记录已存在时,改变 Postgres table 以具有唯一约束

Altering Postgres table to have unique with constraint when duplicates records alredy exist

我们正在使用由 Postgres 支持的 Django ORM。

我们有一些 table ("foo") 有重复的记录,我们想要改变并添加一些唯一的约束,这样就不会插入重复。

为了做到这一点,我们首先需要删除重复的记录,然后添加唯一约束(否则使用alter table添加约束会因为记录重复而失败)。

我想运行以下事务以实现上述流程-

BEGIN WORK;

DELETE FROM foo
WHERE id IN
    (SELECT id
    FROM 
        (SELECT id,
        ROW_NUMBER() OVER( PARTITION BY a1, a2
        ORDER BY  id ) AS row_num
        FROM foo ) t
        WHERE t.row_num > 1 );

LOCK TABLE foo IN SHARE ROW EXCLUSIVE MODE;

DELETE FROM foo
WHERE id IN
    (SELECT id
    FROM 
        (SELECT id,
        ROW_NUMBER() OVER( PARTITION BY a1, a2
        ORDER BY  id ) AS row_num
        FROM foo ) t
        WHERE t.row_num > 1 );

ALTER TABLE "foo" ADD CONSTRAINT "some_constaint_name" UNIQUE ("a1", "a2");

COMMIT WORK;

但是,这失败了 “不能改变 TABLE “foo”,因为它有未决的触发事件”,我想这是有道理的。

如果是这样,我该怎么做才能达到我想要的独特性? 由于 table 具有的数据量,无法将数据复制到新的 table...

我看不出锁或两个删除语句的目的,但要立即执行触发器,运行 在 ALTER TABLE:

之前
SET CONSTRAINTS ALL IMMEDIATE;