【问题标题】:Postgresql: Foreign key violations when importing tables from csv files using copy_expert offered by psycopg2Postgresql:使用 psycopg2 提供的 copy_expert 从 csv 文件导入表时违反外键
【发布时间】:2022-01-18 14:59:20
【问题描述】:

这是问题陈述的再现。

两个表(比如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;") 但这并没有改变任何东西。


解决方案

阿南德·索米蒂兰

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

Foreign Key(A) references B deferrable;

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

【问题讨论】:

    标签: python postgresql csv psycopg2


    【解决方案1】:

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

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

    【讨论】:

    • 禁用触发器只会导致不检查 FK 约束,但是 SET Constraints ALL Deferred' 会影响 UNIQUE、PRIMARY KEY、REFERENCES(外键)和 EXCLUDE 约束。请参阅文档here
    • 要了解如何最初使用Deferrable 创建FK 约束,请参阅此answer
    猜你喜欢
    • 2022-01-27
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    相关资源
    最近更新 更多