Python SQLite - 如何手动开始和结束事务?

4

背景

我正在尝试弄清楚如何在使用 Python 中的 SQLite 时正确地覆盖自动事务。当我尝试运行以下命令时:

cursor.execute("BEGIN;")
.....an assortment of insert statements...
cursor.execute("END;")

I get the following error:

OperationalError: cannot commit - no transaction is active

我知道这是因为Python中的SQLite在每次修改语句(本例中为INSERT)上自动开启一个事务。

问题:

我尝试通过在每几千个记录中执行一次事务来加快插入速度。 如何克服自动打开事务的问题?

2个回答

12

就像@CL所说,你需要将隔离级别设置为None。代码示例:

s = sqlite3.connect("./data.db")
s.isolation_level = None

try:
    c = s.cursor()
    c.execute("begin")
    ...
    c.execute("commit")
except:
    c.execute("rollback")

3
关于这个语句:“如果你想使用自动提交模式,那么将隔离级别设置为None。” 我有一个问题,这是否意味着,在我们将隔离级别设置为None之后,任何种类的DML操作都将自动提交?因此,性能无法提高。我的理解是正确的吗?我从这个网址跳转过来:https://dev59.com/2XTYa4cB1Zd3GeqP0OhR - Clock ZHONG
1
我和@ClockZHONG有同样的担忧。根据我的一些调试,我认为文档是误导性的,它真正应该说的是“如果你想手动处理事务,那么将隔离级别设置为None”。 - Alvaro Gutierrez Perez
2
我在 官方SQLite文档 上找到了这篇文章,它澄清了Python文档中所谓的 "autocommit"。似乎如果没有使用 BEGIN 语句,则所有语句都以“自动提交”模式执行。因此,只要我们用 BEGIN / COMMIT 封闭语句,在隔离级别设置为 None 时就不会有自动提交。希望这可以帮助。 - Alvaro Gutierrez Perez

3
文档中指出:

您可以通过connect()调用的isolation_level参数或连接的isolation_level属性来控制sqlite3隐式执行的BEGIN语句类型(或根本不执行)。

如果您想使用自动提交模式,请将isolation_level设置为None


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