您的位置:首页 > 编程语言 > Python开发

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

2016-12-23 18:10 309 查看
Python 3.6.0的sqlite3模块存在一个bug(见issue 28518),无法执行VACUUM语句。Python 3.6.1已经修复这个bug

一执行就出现异常:

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

这是因为在真正执行VACUUM之前,Python 3.6.0的sqlite3模块(自作主张地)添加了一条BEGIN语句创建了一个事务,而VACUUM不能在事务中执行。

在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的作用:sqlite3模块在开始执行某些SQL语句之前,不再(智能地)自动BEGIN一个事务、或自动COMMIT上一个事务。用户须手动BEGIN一个事务、手动COMMIT之前的修改。

此时(isolation_level=None)程序完全遵照SQLite引擎的行为:在事务以外执行一条SQL语句之后,会立刻COMMIT修改。

尽管sqlite3模块默认的“傻瓜模式”在绝大多数情况下工作良好,个人还是推荐尽量使用isolation_level=None,原因有三:

在个别复杂情况下,傻瓜模式有陷阱,不了解的人容易陷进去。见issue 10740的讨论。

sqlite3模块更透明,sqlite3引擎更简洁。喜欢这种风格。

同一代码在所有版本的Python 3都行得通。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: