在IntegrityError之后继续加载

时间:2010-07-09 11:16:34

标签: python sql sqlite

在python中,我使用importmany填充SQLITE数据库,因此我可以一次导入数万行数据。我的数据包含在元组列表中。我的数据库设置了我想要的主键。

我遇到的问题是主键错误会引发IntegrityError。如果我处理异常,我的脚本会在主键冲突时停止导入。
尝试:

try:
    self.curs.executemany("INSERT into towers values (NULL,?,?,?,?)",self.insertList)
except IntegrityError:
    print "Primary key error"
conn.commit()


所以我的问题是,在使用importmany的python中我可以:

1.捕获违反主键的值?
2.收到主键错误后继续加载数据。

我明白为什么它不会继续加载,因为在异常之后我将数据提交到数据库。我不知道如何继续我离开的地方。

Unforutnley我无法复制并粘贴此网络上的所有代码,任何帮助将不胜感激。现在我没有将PK设置为解决方法...

3 个答案:

答案 0 :(得分:2)

首先要回答(2),如果您想在遇到错误后继续加载,则可以从SQL方面轻松解决此问题:

INSERT OR IGNORE INTO towers VALUES (NULL,?,?,?,?)

这将成功插入没有任何冲突的任何行,并优雅地忽略冲突。但是请注意,IGNORE子句在违反外键时仍然会失败。

您所遇到的冲突解决条款的另一个选择是:INSERT OR REPLACE INTO ...。我强烈推荐SQLite docs,以获取有关冲突和解决冲突的更多信息。

据我所知,您不能同时以一种有效的方式同时完成(1)和(2)。您可能会创建一个在插入之前触发的触发器,以捕获冲突的行,但这将对所有插入施加很多不必要的开销。 (如果可以更聪明的方式,请让我知道。)因此,我建议您考虑是否确实需要捕获冲突行的值,或者是否需要重新设计架构(如果可能/适用)。

答案 1 :(得分:0)

您可以使用lastrowid来确定您停止的位置:

http://docs.python.org/library/sqlite3.html#sqlite3.Cursor.lastrowid

但是,如果您使用它,则无法使用executemany

答案 2 :(得分:0)

使用for循环遍历列表并使用execute而不是executemany。使用try环绕for循环并在异常后继续执行。像这样:

for it in self.insertList:
    try:
        self.curs.execute("INSERT into towers values (NULL,?,?,?,?)",it)
    except IntegrityError:
        #here you could insert the itens that were rejected in a temporary table
        #without constraints for later use (question 1)
        pass
conn.commit()

您甚至可以计算实际插入的列表项目数。