Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Windows关闭后移动sqlite3数据库时出错_Python_Windows_Sqlite - Fatal编程技术网

Python Windows关闭后移动sqlite3数据库时出错

Python Windows关闭后移动sqlite3数据库时出错,python,windows,sqlite,Python,Windows,Sqlite,下面是我的问题的一个简化示例: 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", l

下面是我的问题的一个简化示例:

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
>python test.py
回溯(最近一次呼叫最后一次):
文件“test.py”,第7行,在
重命名('test.db.temp','test.db')
WindowsError:[错误32]该进程无法访问该文件,因为其他进程正在使用该文件

背景:我正在尝试以“原子”方式创建数据库,最简单的方法是在临时位置创建数据库,然后将其移动。

问题是连接对象的上下文管理器似乎无法工作

通过这种方式工作:

db = sqlite3.connect('test.db.temp')
db.executescript('CREATE TABLE foo (bar);')
db.close()
os.rename('test.db.temp', 'test.db')
值得研究的是,为什么它首先实现了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

更新:从这个角度看,与SQLite一起使用时,它看起来像
一起执行事务,因此您的代码类似于:

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

问题是连接对象的上下文管理器似乎不起作用

通过这种方式工作:

db = sqlite3.connect('test.db.temp')
db.executescript('CREATE TABLE foo (bar);')
db.close()
os.rename('test.db.temp', 'test.db')
值得研究的是,为什么它首先实现了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

更新:从这个角度看,与SQLite一起使用时,它看起来像
一起执行事务,因此您的代码类似于:

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')
根据,executescript创建一个游标对象。我猜光标对象不会立即被破坏。尝试在上下文管理器中显式创建游标:

with sqlite3.connect('test.db.temp') as db:
    cur = db.cursor()
    cur.execute('CREATE TABLE foo (bar);')
根据,executescript创建一个游标对象。我猜光标对象不会立即被破坏。尝试在上下文管理器中显式创建游标:

with sqlite3.connect('test.db.temp') as db:
    cur = db.cursor()
    cur.execute('CREATE TABLE foo (bar);')

如果是这种情况,那么正确的解决方法不是添加一个带有cur=
。。。而不是希望它能早点关闭?(注意:我不知道SQLite的Python绑定。)我开始讨论这个例子:这个例子似乎很有趣,它在Xubuntu 14.04上工作,但在Windows7上不工作。必须添加显式db.close()才能在Windows.Interest上工作。无论文件是否已打开,重命名调用都应成功,因为Windows支持重命名当前正在使用的文件(进程的文件句柄未失效)。是的,很抱歉,与光标无关。事实上,它只是用sqlite3.connect('test.db.temp'):pass;
重新编程;;os.rename('test.db.temp','test.db')
如果是这种情况,那么正确的修复方法不是用cur=
添加一个
。。。而不是希望它能早点关闭?(注意:我不知道SQLite的Python绑定。)我开始讨论这个例子:这个例子似乎很有趣,它在Xubuntu 14.04上工作,但在Windows7上不工作。必须添加显式db.close()才能在Windows.Interest上工作。无论文件是否已打开,重命名调用都应成功,因为Windows支持重命名当前正在使用的文件(进程的文件句柄未失效)。是的,很抱歉,与光标无关。事实上,它只是用sqlite3.connect('test.db.temp'):pass;
重新编程;;os.rename('test.db.temp','test.db')
编辑了您的答案,以包含
contextlib.closing
:)sqlite api没有将文件作为contextmanager的一部分关闭,这真是太遗憾了。@AnthonySottile:很好,谢谢!我不知道
contextlib
。将您的答案编辑为包含
contextlib。关闭
:)sqlite api没有将文件作为contextmanager的一部分关闭,真是太遗憾了。@AnthonySottile:很好,谢谢!我不知道
contextlib