我正在从日志文件将记录批量插入数据库。有时(每千行中约有 1 行)其中一行违反了主键并导致事务失败。目前,用户必须手动检查导致失败的文件并删除有问题的行,然后才能尝试重新导入。鉴于有数百个这样的文件需要导入,这是不切实际的。
我的问题:如何跳过违反主键约束的记录插入,而不必执行SELECT
在每行之前声明以查看它是否已经存在?
注意:我知道有一个非常相似的问题#1054695 https://stackoverflow.com/questions/1054695/continue-after-primary-key-violation-error,但这似乎是 SQL Server 特定的答案,我正在使用 PostgreSQL(通过 Python/psycopg2 导入)。
您还可以在事务中使用 SAVEPOINT。
Pythonish 伪代码从应用程序端进行说明:
database.execute("BEGIN")
foreach data_row in input_data_dictionary:
database.execute("SAVEPOINT bulk_savepoint")
try:
database.execute("INSERT", table, data_row)
except:
database.execute("ROLLBACK TO SAVEPOINT bulk_savepoint")
log_error(data_row)
error_count = error_count + 1
else:
database.execute("RELEASE SAVEPOINT bulk_savepoint")
if error_count > error_threshold:
database.execute("ROLLBACK")
else:
database.execute("COMMIT")
编辑:这是 psql 中的一个实际示例,基于文档中示例的细微变化(SQL 语句以 ">" 为前缀):
> CREATE TABLE table1 (test_field INTEGER NOT NULL PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "table1_pkey" for table "table1"
CREATE TABLE
> BEGIN;
BEGIN
> INSERT INTO table1 VALUES (1);
INSERT 0 1
> SAVEPOINT my_savepoint;
SAVEPOINT
> INSERT INTO table1 VALUES (1);
ERROR: duplicate key value violates unique constraint "table1_pkey"
> ROLLBACK TO SAVEPOINT my_savepoint;
ROLLBACK
> INSERT INTO table1 VALUES (3);
INSERT 0 1
> COMMIT;
COMMIT
> SELECT * FROM table1;
test_field
------------
1
3
(2 rows)
请注意,值 3 是在错误之后插入的,但仍在同一事务中!
SAVEPOINT 的文档位于http://www.postgresql.org/docs/8.4/static/sql-savepoint.html http://www.postgresql.org/docs/8.4/static/sql-savepoint.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)