在每个 cursor.execute() 之后是不是需要 connection.commit()?

Posted

技术标签:

【中文标题】在每个 cursor.execute() 之后是不是需要 connection.commit()?【英文标题】:Is connection.commit() needed after each cursor.execute()?在每个 cursor.execute() 之后是否需要 connection.commit()? 【发布时间】:2018-07-03 22:00:05 【问题描述】:

在执行connection.commit() 之前多次对cursor.execute(…) 进行有效的Pymysql 操作,或者是否需要在每个执行语句之后发生connection.commit() 才能正确存储结果?这个想法是消除尽可能多的冗余语句,因为该过程是长时间运行的。

代码结构:

with connection.cursor() as cursor:
    …
    cursor.execute(SQLtype1, rowToInsert)

    cursor.execute(SQLtype2, otherToInsert)

    connection.commit() # does this account for both execute statements, or just the last?

我查看了以下内容:

PyMySQL execute/commit example,但只有一个示例只有一个执行语句。

Python MySQLdb example,但有一个示例显示每个执行语句之后的提交

Python SQLite example,在提交前显示多个执行语句,但不确定SQLite是否处理不同

注意:由于 SQL 查询不同,executemany 似乎不是一个选项。

【问题讨论】:

【参考方案1】:

不,这是cursor.commit() 的预期目的。您所描述的是自动提交,它可能会或可能不会为您的数据库驱动程序启用。检查其文档以确保。

如果您的第一个查询成功但第二个查询失败,您可能不希望您的数据库处于损坏状态,即插入了一些行但没有插入其他行。您执行的所有更改都会暂存,直到您使用cursor.commit() 将它们提交到数据库。这允许您一次执行多个查询,并在其中一个失败时自动回滚更改。

【讨论】:

如果我理解你的意思,你是说我会通过在每个执行语句之后调用 commit 来复制自动提交的功能。但是,使用自动提交来避免潜在的损坏状态可能更安全。 @Phillip:不完全是。假设您运行 PayBuddy,用户 A 向用户 B 发送了 1,000 美元。您可以通过首先减少 userA 的余额然后增加 userB 的余额来做到这一点。这两个查询必须成功,否则整个事务将失败。您不能让 userA 缺少 100 美元,而 userB 由于您的应用程序出现一些错误而没有收到它。您不应该在两个查询之间提交更改,因为这会使您的数据库暂时处于不一致的状态。如果您有无法部分执行的查询组,您希望避免自动提交。 @Blender,感谢您的详细回答...请跟进问题:您可以在单笔交易中包含的查询数量是否有限制? (成百上千?) .... 同样,在给定时间内应该多久执行一次提交是否有限制或范围? .... [RE:我正在抓取约 100k pdf,每页约 12 页,这将需要在约 37 个表上持续约 4 小时的“插入”语句] ...再次感谢!

以上是关于在每个 cursor.execute() 之后是不是需要 connection.commit()?的主要内容,如果未能解决你的问题,请参考以下文章

python怎么判断mysql中是不是存在某个表

如何将参数传递给`pymssql`中的`cursor.execute`?

Django 中的游标是不是在打开的事务中运行?

Python PostgreSQL 语句问题 psycopg2 cursor.execute(Table Union)

python连接MySQL数据库问题? cursor( ) 、execute()和fetc

pyspark 中 spark.sql() 和 cursor.execute 的区别?