这是我的问题的一个简单的例子:
import os import sqlite3 with sqlite3.connect('test.db.temp') as db: db.executescript('CREATE TABLE foo (bar);') os.rename('test.db.temp', 'test.db')
输出:
> python test.py Traceback (most recent call last): File "test.py", line 7, in <module> os.rename('test.db.temp', 'test.db') WindowsError: [Error 32] The process cannot access the file because it is being used by another process
背景:我试图以“primefaces”方式创build数据库,最简单的方法是在临时位置创build数据库,然后移动它。
问题是连接对象的上下文管理器似乎不工作。
这样它的工作原理:
db = sqlite3.connect('test.db.temp') db.executescript('CREATE TABLE foo (bar);') db.close() os.rename('test.db.temp', 'test.db')
值得研究为什么它首先实现了__enter__/__exit__
…
更新:从这个答案看起来像与SQLite with
使用做一个事务,所以你的代码是类似于:
db = sqlite3.connect('test.db.temp') db.begin_transaction() db.executescript('CREATE TABLE foo (bar);') db.commit() os.rename('test.db.temp', 'test.db')
因此,重新命名时,数据库显然仍然打开。 推荐的代码会是这样的:
with contextlib.closing(sqlite3.connect('test.db.temp')) as db: db.executescript('CREATE TABLE foo (bar);') os.rename('test.db.temp', 'test.db')
根据文档 , 执行脚本创建一个游标对象。 我猜游标对象不会立即被破坏。 尝试在上下文管理器中显式创建一个游标:
with sqlite3.connect('test.db.temp') as db: cur = db.cursor() cur.execute('CREATE TABLE foo (bar);')