是否有可能在postgres中捕获外键违规

时间:2016-06-11 18:58:40

标签: postgresql psycopg2

我正在尝试将数据插入到具有外键约束的表中。如果我正在插入的行中存在约束违规,我想要删除该数据。

问题是每次违反约束时postgres都会返回错误。我是否有可能在我的插入语句中有一些声明,比如'ON FOREIGN KEY CONSTRAINT DOHINGHING'?

编辑:

这是我正在尝试的查询,其中info是dict:

cursor.execute("INSERT INTO event (case_number_id, date, \
session, location, event_type, worker, result) VALUES \
(%(id_number)s, %(date)s, %(session)s, \
%(location)s, %(event_type)s, %(worker)s, %(result)s) ON CONFLICT DO NOTHING", info)

出现外键违规时出错

1 个答案:

答案 0 :(得分:3)

如果您一次只插入一行,则可以在插入之前创建savepoint,在插入失败时创建rollback(或者在插入时release it成功)。

对于Postgres 9.5或更高版本,您可以使用INSERT ... ON CONFLICT DO NOTHING来完成它所说的内容。您也可以 编写ON CONFLICT DO UPDATE SET column = value...,它会自动将您的插入转换为您要与之冲突的行的更新(此功能有时称为“upsert”)。

这不起作用,因为OP正在处理外键约束而不是唯一约束。在这种情况下,您可以最轻松地使用我之前描述的保存点方法,但对于多行,它可能会显得乏味。如果你需要一次插入多行,那么将它们分成多个插入语句应该是合理的,提供你不是working in autocommit mode,所有插入都发生在一个事务中,你是不插入大量的行。

有时,您确实需要在单个语句中插入多个插件,因为与数据库通信的往返开销加上每个插件上保存点的成本实在太高了。在这种情况下,存在许多不完美的方法。可能最不好的是构建一个嵌套查询,它选择你的数据并将它与另一个表连接起来,如下所示:

INSERT INTO table_A (column_A, column_B, column_C)
SELECT A_rows.*
FROM VALUES (...) AS A_rows(column_A, column_B, column_C)
JOIN table_B ON A_rows.column_B = table_B.column_B;