为什么在单元测试中运行时会出现“无法打开数据库文件”的情况?
- 2025-03-19 08:56:00
- admin 原创
- 4
问题描述:
为什么我无法打开我的 SQLite 数据库?我通过的单元测试“/tmp/cer/could.db”可以毫无问题地创建数据库,但是当我通过实际程序时,我得到的是相同的位置:
OperationalError:无法打开数据库文件
我尝试使用空数据库、省略数据库和单元测试以及根本没有数据库,但出现了同样的错误。
解决方案 1:
初步诊断:SQLite 由于某种原因无法打开该文件。
检查显而易见的原因,并按照我建议的大致顺序进行检查:
该程序是否在您测试的同一台机器上运行?
它是以您的身份运行的(或者至少是以与您测试它相同的用户身份运行的)吗?
磁盘是否
/tmp
已满?(您使用的是 Unix,因此用它df /tmp
来查找。)该
/tmp/cer
目录是否具有“奇怪”的权限?(SQLite 需要能够在其中创建其他文件才能处理提交日志之类的内容。)单元测试代码是否仍在使用该数据库?(使用足够现代的 SQLite 并在正确的文件系统中时,可以进行并发打开 - 尽管实际上
/tmp
总是在正确的 FS 上,所以可能并非如此 - 但仍然不推荐。)开发代码是否真的试图写入该数据库,还是某些“聪明”的东西让你措手不及,并导致它尝试打开其他东西?(我过去在我的代码中就遇到过这种情况;不要以为这不会发生在你身上……)
您在单元测试和生产代码中使用相同版本的 SQLite 库吗?
如果您不在同一台机器上,则生产系统很可能没有/tmp/cer
目录。显然首先要解决这个问题。同样,如果您在同一台机器上但以不同的用户身份运行,则可能会遇到权限/所有权问题。磁盘空间是另一个严重的问题,但可能性较小。我不认为是最后三个,但如果更明显的部署问题得到解决,则值得检查它们。如果以上都不是,那么您遇到了一个奇怪的问题,必须报告更多信息(它甚至可能是 SQLite 中的一个错误,但了解它的开发人员,我相信这种情况不太可能发生)。
解决方案 2:
这对我有用:
conn = sqlite3.connect("C:\/users\\guest\\desktop\\example.db")
注意:完整路径中的双斜杠
在 Win 7 企业版和 Win Xp Pro 上使用python v2.7
解决方案 3:
~
在 unix 上,使用用户目录的快捷方式时出现该错误。更改它以/home/user
解决该错误。
解决方案 4:
一个原因可能是在与数据库指定的路径不匹配的路径中运行代码。例如,如果您的代码中有:
conn = lite.connect('folder_A/my_database.db')
folder_A
如果你在或其他没有 的地方运行代码,folder_A
就会引发此类错误。原因是如果数据库文件不存在,SQLite 将创建该数据库文件而不是文件夹。
解决此问题的另一种方法可能是将连接命令包装在try-except
表达式中,并在引发时创建目录sqlite3.OperationalError
。
从 os 导入 mkdir 导入 sqlite3 作为 lite
try:
conn = lite.connect('folder_A/my_database.db')
except lite.OperationalError:
mkdir('folder_A')
finally:
conn = lite.connect('folder_A/my_database.db')
解决方案 5:
在我的例子中,我尝试在文件夹中创建 sqlite db /tmp
,但在所有的斜杠中我漏掉了一个斜杠
而不是sqlite:///tmp/mydb.sqlite
-> sqlite:////tmp/mydb.sqlite
...
解决方案 6:
temp_store_directory
尝试在完全有效的数据库上创建索引时遇到此问题。事实证明,如果 sqlite变量/目录不可写,则会抛出此错误(除了此处描述的其他原因) 。
解决方案:将其更改temp_store_directory
为c.execute(f'PRAGMA temp_store_directory = "{writable_directory}"')
。请注意,此指令已被弃用,我还不确定将用什么来替代。
解决方案 7:
如果有人在遇到该错误后再次访问这里,则有效的 SQLite URL 格式为以下任一种:
sqlite:///:memory: (or, sqlite://)
sqlite:///relative/path/to/file.db
sqlite:////absolute/path/to/file.db
解决方案 8:
我在 Windows 7 上遇到了同样的问题。我的数据库名称是,test
并且我收到错误:
self.connection = Database.connect(**kwargs)
sqlite3.OperationalError: unable to open database file
我test
用和替换test.db
,一切顺利。
解决方案 9:
您唯一需要做的就是创建文件夹(因为它尚不存在),程序只会创建数据库文件。这对我来说真的很有效!
解决方案 10:
就我而言,解决方案是使用绝对路径来查找现有文件:
import os.path
filepath = os.path.abspath(filepath)
# Leave this out if the file doesn't exist yet
assert os.path.exists(filepath), "The file doesn't exist"
conn = sqlite3.connect(filepath)
我不知道为什么这个修复有效:路径只包含 ASCII 字符,没有空格。但它仍然有所不同。
供参考:Windows 7,Python 3.6.5(64位)。
我无法在另一台机器(也是 Windows 7、Python 3.6.4 64 位)上重现该问题,所以我不知道这个修复为什么有效。
解决方案 11:
import sqlite3
connection = sqlite3.connect("d:\\pythonAPI\\data.db")
cursor = connection.cursor()
create_table = "CREATE TABLE users (id int, username text, password text)"
cursor.execute(create_table)
如果你没有弄清楚,可以找到更清晰的完整路径
解决方案 12:
这肯定是权限问题。如果有人在 Linux 上遇到此错误,请确保您使用以下命令运行命令,sudo
因为该文件很可能由 root 拥有。希望这能有所帮助!
解决方案 13:
使用完全分类的数据库文件名称
使用- /home/ankit/Desktop/DS/Week-7-MachineLearning/Week-7-MachineLearning/soccer/database.sqlite
反而-
解决方案 14:
如果在能够正确访问数据库(并且没有任何设置发生更改)后随机发生这种情况,则可能是数据库损坏造成的。
在我尝试同时从两个进程写入我的数据库后出现此错误,这一定损坏了我的 db.sqlite3 文件。
我的解决方案是恢复到损坏发生之前的先前提交。
解决方案 15:
在 Windows 上遇到错误,添加了 assert os.path.exists,仔细检查了路径,以管理员身份运行脚本,但没有任何帮助。
事实证明,如果您将文件夹添加到 Windows Defender 的勒索软件防护中,您将无法再使用其他程序在那里写入,除非您将这些程序添加到受控文件夹访问的白名单中。
解决方案 - 检查您的文件夹是否已添加到 Windows Defender 的勒索软件防护中,并将其删除以便更快地修复。
解决方案 16:
确保在尝试运行 syncdb 时没有编辑 settings.py 文件,否则您将收到相同的错误!!!
self.connection = Database.connect(**kwargs)
sqlite3.OperationalError: unable to open database file
解决方案 17:
1)验证你的数据库路径,检查你的 settings.py
DATABASES = {
'default': {
'CONN_MAX_AGE': 0,
'ENGINE': 'django.db.backends.sqlite3',
'HOST': 'localhost',
'NAME': os.path.join(BASE_DIR, 'project.db'),
'PASSWORD': '',
'PORT': '',
'USER':''
有时不会有 NAME': os.path.join(BASE_DIR, 'project.db'),
2)确保目标文件夹的权限和所有权
对我来说很有效,
解决方案 18:
我的理由很愚蠢。我把 manage.py 放到了终端上,所以它使用完整路径运行。而且我更改了项目文件夹的名称。所以现在,程序无法找到包含先前数据的文件,因此出现错误。
在这种情况下,请确保重新启动软件。
解决方案 19:
对于任何有与此问题相关的气流问题的人。
在我的例子中,我已初始化 airflow/root/airflow
并以root身份运行其调度程序。我在运行任务实例时使用该run_as_user
参数模拟Web用户。但是 airflow 始终无法触发我的 DAG,日志中出现以下错误:
sqlite3.OperationalError: unable to open database file
...
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
我还发现,一旦我手动触发 DAG,就会在 下自动创建一个新的 airflow 资源目录/home/web
。我不清楚这种行为,但我通过从 中删除整个 airflow 资源/root
、在 下重新初始化 airflow 数据库并在 下以web/home/web
形式运行调度程序来使其工作:
[root@host ~]# rm -rf airflow
[web@host ~]$ airflow initdb
[web@host ~]$ airflow scheduler -D
如果您想尝试这种方法,我可能需要在做任何事情之前备份您的数据。