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语句是不能在事务中执行的,因此出现了异常。