WindowsErrorclosures后移动sqlite3数据库

这是我的问题的一个简单的例子:

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);')