是否有可能在 postgres 中发现外键违规
Is it possible to catch a foreign key violation in postgres
我正在尝试将数据插入到具有外键约束的 table 中。如果我插入的一行中存在约束违规,我想丢弃该数据。
问题是 postgres returns 每次我违反约束时都会出错。我是否可以在我的插入语句中包含一些语句,例如 'ON FOREIGN KEY CONSTRAINT DO NOTHING'?
编辑:
这是我正在尝试执行的查询,其中 info 是一个字典:
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)
当存在外键违规时出错
如果您一次只插入一行,则可以在插入成功时创建一个 savepoint before the insert and rollback to it when the insert fails (or release it。
对于 Postgres 9.5 或更高版本,您可以使用 INSERT ... ON CONFLICT DO NOTHING
来实现它所说的。您可以 也 编写 ON CONFLICT DO UPDATE SET column = value...
,这将自动将您的插入转换为与您冲突的行的更新(此功能有时称为 "upsert")。
这不起作用,因为 OP 正在处理 外键 约束而不是 unique 约束。在这种情况下,您可以最轻松地使用我之前描述的保存点方法,但对于多行,它可能会很乏味。如果您需要一次插入多行,将它们拆分为多个插入语句应该是合理的性能,提供您不是working in autocommit mode,所有插入都发生在一个事务中,而且您没有插入大量行。
有时,您确实需要在单个语句中进行多次插入,因为与数据库对话的往返开销加上在每次插入时都保存点的成本实在是太高了。在这种情况下,有许多不完善的方法。 最不坏的可能是构建一个嵌套查询,它选择您的数据并将其与其他数据相结合table,像这样:
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;
我正在尝试将数据插入到具有外键约束的 table 中。如果我插入的一行中存在约束违规,我想丢弃该数据。
问题是 postgres returns 每次我违反约束时都会出错。我是否可以在我的插入语句中包含一些语句,例如 'ON FOREIGN KEY CONSTRAINT DO NOTHING'?
编辑:
这是我正在尝试执行的查询,其中 info 是一个字典:
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)
当存在外键违规时出错
如果您一次只插入一行,则可以在插入成功时创建一个 savepoint before the insert and rollback to it when the insert fails (or release it。
对于 Postgres 9.5 或更高版本,您可以使用 INSERT ... ON CONFLICT DO NOTHING
来实现它所说的。您可以 也 编写 ON CONFLICT DO UPDATE SET column = value...
,这将自动将您的插入转换为与您冲突的行的更新(此功能有时称为 "upsert")。
这不起作用,因为 OP 正在处理 外键 约束而不是 unique 约束。在这种情况下,您可以最轻松地使用我之前描述的保存点方法,但对于多行,它可能会很乏味。如果您需要一次插入多行,将它们拆分为多个插入语句应该是合理的性能,提供您不是working in autocommit mode,所有插入都发生在一个事务中,而且您没有插入大量行。
有时,您确实需要在单个语句中进行多次插入,因为与数据库对话的往返开销加上在每次插入时都保存点的成本实在是太高了。在这种情况下,有许多不完善的方法。 最不坏的可能是构建一个嵌套查询,它选择您的数据并将其与其他数据相结合table,像这样:
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;