将仅唯一的行插入SQLite(Python)

14

我正在使用cursor.executemany插入来自CSV文件的一批行到SQLite表中,其中一些基于主键字段预计会是重复的。当我执行命令时,可预测地会出现完整性错误,并且没有插入任何内容。

如何有选择地只插入非重复行,而不必事先手动筛选它们?我知道在纯Python中,你可以简单地创建一个错误异常并跳过重复行 - 在这种情况下是否有类似的实现方法?


您可以EAFP每个批次,在出现完整性错误时,可以回到逐行插入而不是对于该批量使用executemany;同样,只需EAFP每一行并忽略IntegrityError。 - Paulo Scardine
好的,我想我明白了。我对SQLite还很陌生——但这是不是我想要用BEGIN/END事务来包装它以使其更有效率的东西? - ChrisArmstrong
3个回答

28

“重复项”是指具有与另一行或任何列相同的主键的行? - Iulian Onofrei
请参阅SQLite文档中的ON CONFLICT子句。 它是任何触发冲突的行,通常是由于UNIQUE约束,但也可能是CHECK或其他约束。 最常见的唯一约束是主键。 - schlenk

4

一种选择是手动编写循环并添加错误捕获,而不是使用 executemany

伪代码:

for row in csvfile:
   try:
       cursor.execute('INSERT INTO X (Y) VALUES (%s)' % row[rowdatapoint])
   except IntegrityError:
       pass

也许没有 executemany 那么高效,但它会在不涉及更复杂的SQL更改(可能需要预先生成巨大的INSERT SQL字符串)之前捕获您的错误。


2
在批量插入中存在重复记录会导致整个批次失败,这是一件痛苦的事情。然而,ON CONFLICT子句是INSERT子句的扩展,可以消除重复记录的障碍。有多个SQLite子句可用于处理此类情况: INSERT OR IGNORE忽略重复记录 INSERT OR REPLACE用最小值替换最新的重复记录
更多解释:
1. https://sqlite.org/lang_conflict.html 2. https://sqlite.org/lang_insert.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接