Postgresql:使用 psycopg2 提供的 copy_expert 从 csv 文件导入表时发生外键冲突

Postgresql: Foreign key violations when importing tables from csv files using copy_expert offered by psycopg2

这里是问题陈述的再现。

两个表(例如 Tab1Tab2)的数据库模式已在名为(例如)schemas.ddl 的文件中给出。这两个表之间存在多个完整性约束(包括外键)。 data1.csvdata2.csv分别给出了这两个表的数据。我需要将这些 csv 文件中的数据放入表格中。

我是这样做的:

import psycopg2

conn = psycopg2.connect(database=postgres, user=postgres, host=localhost, port=5432)
cur = conn.cursor()

# Execute the schema, this works fine
cur.execute(open(schemas.ddl, "r").read())

files = ["data1.csv", "data2.csv"]

# Iterate through files to add data
for i in range(1,3):
    copy_sql = "copy Tab"+str(i)+" from stdin with csv header delimiter as ',' null as 'null'"
    with open(files[i-1],'r') as f:
        cur.copy_expert(sql=copy_sql, file=f)

也就是说,我使用如图所示的copy_expert()来复制第一个文件的数据,然后复制第二个文件的数据。但是,这会导致在输入数据时违反外键约束(和其他自定义约束)。

有没有办法在提交时检查输入数据的完整性,而不是在每个命令之后?我已经尝试 cur.execute("SET CONSTRAINTS ALL DEFERRED;") 但这并没有改变任何东西。


解决方案

作者:Anand Sowmithiran

只需将外键和约束设置为deferrable。示例:

Foreign Key(A) references B deferrable;

或者如果您相信数据是正确的,只需禁用所有触发器并在复制后重新启用它们。

这些 FK 约束最初必须使用 DEFERRABLE 创建,然后才能使用 SET 命令延迟。或者,您可以关闭这 2 个表上的所有 triggers,然后执行大容量复制操作,然后启用触发器。 PG 使用触发器来执行 FK 约束。

ALTER TABLE tab2 DISABLE TRIGGER ALL;
 --run your program---
--and then enable triggers
ALTER TABLE tab2 ENABLE TRIGGER ALL;