1

我在 python 中使用 psycopg2,但我的问题是 DBMS 不可知论(只要 DBMS 支持事务):

我正在编写一个将记录插入数据库表的 python 程序。要插入的记录数超过一百万。当我编写代码以便在每个插入语句上运行提交时,我的程序太慢了。因此,我更改了我的代码以每 5000 条记录运行一次提交,速度上的差异是巨大的。

我的问题是,在插入记录时会在某些时候发生异常(某些完整性检查失败),我希望将我的更改提交到该点,当然,导致异常发生的最后一个命令除外,并继续其余的我的插入语句。

我还没有找到实现这一目标的方法;我实现的唯一一件事就是捕获异常,回滚我的事务并从那个点继续,在那里我松开了我挂起的插入语句。此外,我尝试(深度)复制光标对象和连接对象也没有任何运气。

有没有办法直接或间接地实现此功能,而无需回滚并重新创建/重新运行我的语句?

谢谢大家,

乔治。

4

2 回答 2

3

我怀疑你会找到一种快速的跨数据库方法来做到这一点。当一个条目导致批处理失败时,您只需优化批处理大小带来的速度增益和重复工作的速度成本之间的平衡。

一些 DB 可以在出错后继续进行事务,但 PostgreSQL 不能。但是,它确实允许您使用该SAVEPOINT命令创建子事务。这些远非免费,但它们的成本低于完整交易。所以你可以做的是每(比如)100 行,发出 aSAVEPOINT然后释放之前的保存点。如果你遇到错误,ROLLBACK TO SAVEPOINT提交,然后从你离开的地方继续。

于 2012-12-12T11:29:02.007 回答
2

如果您在每 5000 个记录间隔后提交事务,您似乎可以对输入数据进行一些预处理,并将其分解为 5000 个记录块的列表,即[[[row1_data],[row2_data]...[row4999_data]],[[row5000_data],[row5001_data],...],[[....[row1000000_data]]]

然后运行您的插入,并跟踪您正在处理的块以及您当前正在插入的记录。当您收到错误时,您重新运行该块,但跳过有问题的记录。

于 2012-12-12T22:38:33.227 回答