Python 3.6.0的sqlite3模块无法执行VACUUM语句

时间:2024-04-11 18:34:59

Python 3.6.0的sqlite3模块存在一个bug(见issue 29003),无法执行VACUUM语句。

一执行就出现异常:

Traceback (most recent call last):
  File "D:\desktop\cannot_vacuum.py", line 25, in <module>
    conn.execute('VACUUM')
sqlite3.OperationalError: cannot VACUUM from within a transaction

这个bug也许会在Python 3.6.1中解决。

在Python 3.6.0,要想让程序正常运行,需要在connect时设置isolation_level参数为None,如下:

conn = sqlite3.connect('test.db', isolation_level=None)

或者这样做:

conn = sqlite3.connect('test.db')
conn.isolation_level = None

查看文档,isolation_level=None表示自动commit:

If you want autocommit mode, then set isolation_level to None.

Otherwise leave it at its default, which will result in a plain “BEGIN” statement, or set it to one of SQLite’s supported isolation levels: “DEFERRED”, “IMMEDIATE” or “EXCLUSIVE”.

Changed in version 3.6: sqlite3 used to implicitly commit an open transaction before DDL statements. This is no longer the case.

如果保持isolation_level为默认值,则会在执行每条SQL语句之前,自动加上"BEGIN"语句,从而形成一个事务。

而VACUUM语句是不能在事务中执行的,因此出现了异常。