在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设置为解决方法...
答案 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()
您甚至可以计算实际插入的列表项目数。