【问题标题】:Sqlite3, OperationalError: unable to open database fileSqlite3,OperationalError:无法打开数据库文件
【发布时间】:2011-06-05 22:29:15
【问题描述】:

问题:为什么我打不开数据库?


信息:我正在使用sqlite3 数据库进行项目。我编写了一个测试程序,它运行并将其传递给数据库:

/tmp/cer/could.db

单元测试程序可以使db没有任何问题。但是,当我实际使用将相同位置传递给它的程序时,出现以下错误:

OperationalError: 无法打开数据库文件

我试过这样做:

1) an empty database.
2) the database and the unit test left behind.
3) no database at all.

在三种情况下,我得到了上述错误。最令人沮丧的部分是unittest 可以做到这一点,但实际程序却不能。

关于到底发生了什么的任何线索?

【问题讨论】:

  • 这是完整路径吗?您确定您没有通过环境变量或~ 或其他一些简短形式传递路径吗?
  • /tmp/cer/目录是否存在?
  • @chrisaycook:是的。我不是。 @thkala:确实如此。
  • 遇到了同样的错误,原来我的文件名中有一个冒号':',而sqlite不喜欢它。把它拿出来,就像一个魅力。

标签: python sqlite


【解决方案1】:

初步诊断:SQLite 由于某种原因无法打开该文件。

检查明显的原因,以及我建议检查的大致顺序:

  • 程序是否与您正在测试的机器在同一台机器上运行?
  • 它是否以您的身份运行(或至少与您测试它的用户相同)?
  • 包含/tmp 的磁盘是否已满? (您使用的是 Unix,因此请使用 df /tmp 查找。)
  • /tmp/cer 目录是否有“奇数”权限? (SQLite 需要能够在其中创建其他文件才能处理诸如提交日志之类的事情。)
  • 单元测试代码是否仍在使用该数据库? (使用足够现代的 SQLite 并且在正确的文件系统中时,并发打开 可能的 - 尽管 /tmp 几乎总是在正确的 FS 上,所以它可能不是这样 - 但仍然不推荐。 )
  • 开发代码是真的试图写入该数据库,还是“聪明”的东西让你发现并导致它尝试打开其他东西? (我过去在我的代码中就被这个发现了;不要以为它不会发生在你身上……)
  • 您是否在单元测试和生产代码中使用相同版本的 SQLite 库?

如果您不在同一台机器上,则生产系统很可能没有/tmp/cer 目录。显然要先解决这个问题。同样,如果您在同一台机器上但以不同的用户身份运行,您可能会遇到权限/所有权问题。磁盘空间是另一个严重的问题,但可能性较小。我不认为这是最后三个,但如果对更明显的部署问题进行了排序,它们值得检查。如果以上都不是,那么您遇到了一个奇怪的问题,并且必须报告更多信息(它甚至可能是 SQLite 中的一个错误,但了解它的开发人员,我认为这不太可能)。

【讨论】:

  • 是的。是的。不。从来没听说过。不应该。不。数据库是由同一个系统创建的,唯一的区别是 UTFile.py 调用它而不是 cSystem.py。是的,我使用的是 Python 自带的内置 SQLite 版本。
  • 发现了我的问题。字符串并不完全相同。由于我的配置文件,略有不同。配置文件在我的路径中留下了换行符,所以我试图打开:'/tmp/cer/\ncloud.db' 有我的问题。但这是一个非常好的答案。谢谢!
  • 谢谢!我遇到了这个问题,它确实缺乏 Web 服务器用户对目录的写权限,即使该文件对该用户具有写权限。
  • 我遇到了同样的问题。虽然数据库有777权限,但它所在的目录是755,将其更改为777也可以解决问题。您关于“奇怪权限”的提示对我有帮助。
  • 我遇到了同样的问题,但是在 docker 容器中,我应该怎么做?
【解决方案2】:

这对我有用:

conn = sqlite3.connect("C:\\users\\guest\\desktop\\example.db")

注意:完整路径中的双斜杠

在 Win 7 企业版和 Win Xp Pro 上使用 python v2.7

希望这对某人有所帮助。

【讨论】:

  • 在 ubuntu 上,反斜杠也有帮助:create_engine("sqlite:///data\db_folder\example.db")
  • 您的代码中根本没有斜杠,只有反斜杠,实际上只有其中一个,因为它们需要转义。
【解决方案3】:

在 unix 上,我在为用户目录使用 ~ 快捷方式时遇到了该错误。 将其更改为 /home/user 解决了该错误。

【讨论】:

  • 这里也一样,虽然我很想知道为什么这是有道理的。 sqlite 不允许 ~ 作为家庭参考吗?
【解决方案4】:

一个原因可能是在与您为数据库指定的路径不匹配的路径中运行代码。例如,如果您的代码中有:

conn = lite.connect('folder_A/my_database.db')

如果您在folder_A 或其他没有folder_A 的地方运行代码,则会引发此类错误。原因是如果文件夹不存在,SQLite 会创建数据库文件。

解决此问题的另一种方法可能是将连接命令包装在 try-except 表达式中,并在引发 sqlite3.OperationalError 时创建目录。

从操作系统导入 mkdir 将 sqlite3 导入为精简版

try:
    conn = lite.connect('folder_A/my_database.db')
except lite.OperationalError:
    mkdir('folder_A')
finally:
    conn = lite.connect('folder_A/my_database.db')

【讨论】:

  • 谢谢!这就是我一直在寻找的。此外,else 在这里不是多余的吗,因为每当触发子句时总是会创建 conn 对象?此外,将else 子句中的语句移动到except 部分并添加finallyconn.close() 会更惯用吗?
  • 是的,感谢您的注意。 “else”部分实际上应该是“finally”。也不需要在创建后立即关闭连接。
  • 这正是我遇到的,我应该抓住它......
  • +1 这也是我的问题,但由于有时我使用之前创建的文件夹(尤其是/tmp),所以有点难找。顺便说一句,try/except 的替代方法是始终在使用前创建(如果有多个嵌套级别,则与父母一起创建):import pathlib; pathlib.Path(folder).mkdir(parents=True, exist_ok=True)
【解决方案5】:

尝试在完全有效的数据库上创建索引时遇到了这个问题。事实证明,如果 sqlite temp_store_directory 变量/目录不可写,它会抛出这个错误(除了这里描述的其他原因)。

解决方案:将temp_store_directory 更改为c.execute(f'PRAGMA temp_store_directory = "{writable_directory}"')。请注意这个 pragma is being deprecated,我还不确定替换会是什么。

【讨论】:

    【解决方案6】:

    在我的例子中,我尝试在 /tmp 文件夹中创建 sqlite db,并且从所有斜杠中我错过了一个斜杠

    而不是sqlite:///tmp/mydb.sqlite -> sqlite:////tmp/mydb.sqlite ...

    【讨论】:

    【解决方案7】:

    我在 Windows 7 上遇到了同样的问题。我的数据库名称是 test,我得到了错误:

    self.connection = Database.connect(**kwargs)
    sqlite3.OperationalError: unable to open database file
    

    我将test 替换为test.db,一切顺利。

    【讨论】:

      【解决方案8】:

      您唯一需要做的就是创建文件夹(因为它还不存在),程序只会创建数据库文件。 这对我真的很管用!

      【讨论】:

        【解决方案9】:

        就我而言,解决方案是使用绝对路径来查找现有文件:

        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 位)上重现该问题,所以我不知道为什么此修复有效。

        【讨论】:

        • 我遇到了同样的问题,结果发现我的笔记本在与我的数据库相邻的文件夹中运行(例如 source>notebooks 和 source>db>database.db)。绝对路径解决了。
        【解决方案10】:
        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)
        


        如果您没有弄清楚,可以更清晰的完整路径

        【讨论】:

        • 使用 2 个反斜杠对我有用,谢谢!
        【解决方案11】:

        这绝对是权限问题。如果有人在 linux 上遇到此错误,请确保您使用 sudo 运行命令,因为该文件很可能归 root 所有。希望对您有所帮助!

        【讨论】:

          【解决方案12】:

          使用数据库文件的完全分类名称

          使用-/home/ankit/Desktop/DS/Week-7-MachineLearning/Week-7-MachineLearning/soccer/database.sqlite

          改为-

          【讨论】:

            【解决方案13】:

            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)确保目标文件夹的权限和所有权

            它对我有用,

            【讨论】:

              【解决方案14】:

              如果在能够正确访问您的数据库后随机发生这种情况(并且没有更改任何设置),则可能是数据库损坏

              我在尝试同时从两个进程写入我的数据库后收到此错误,它一定损坏了我的 db.sqlite3 文件。

              我的解决方案是恢复到损坏发生之前的先前提交。

              【讨论】:

                【解决方案15】:

                在 Windows 上遇到错误,添加了 assert os.path.exists,仔细检查了路径,以管理员身份运行脚本,没有任何帮助。

                事实证明,如果您将文件夹添加到 Windows Defender 的勒索软件保护中,除非您将这些程序添加到受控文件夹访问的白名单中,否则您将无法再使用其他程序在那里进行写入。

                解决方案 - 检查您的文件夹是否已添加到 Windows Defender 的勒索软件保护中并将其删除以加快修复速度。

                【讨论】:

                • 我发现以管理员身份运行 powershell 可以正常工作。
                【解决方案16】:

                确保你在尝试运行syncdb时没有编辑settings.py文件,你会得到同样的错误!!!

                self.connection = Database.connect(**kwargs)
                sqlite3.OperationalError: unable to open database file
                

                【讨论】:

                  【解决方案17】:

                  我的理由很愚蠢。 我已将 manage.py 放到终端上,因此它使用完整路径运行。 我已经更改了项目文件夹的名称。 所以现在,程序无法找到包含先前数据的文件,因此出现错误。

                  确保在这种情况下重新启动软件。

                  【讨论】:

                    【解决方案18】:

                    对于与此问题相关的气流问题的任何人。

                    在我的例子中,我已经在 /root/airflow 中初始化了气流,并以 root 身份运行它的调度程序。我在运行任务实例时将run_as_user 参数用于impersonate web 用户。然而,气流总是无法触发我的 DAG,并在日志中出现以下错误:

                    sqlite3.OperationalError: unable to open database file
                    ...
                    sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
                    

                    我还发现,一旦我手动触发了 DAG,就会在/home/web 下自动创建一个新的气流资源目录。我不清楚这种行为,但我通过从/root 中删除整个气流资源,重新初始化/home/web 下的气流数据库并将调度程序运行为 web 下:

                    [root@host ~]# rm -rf airflow
                    [web@host ~]$ airflow initdb
                    [web@host ~]$ airflow scheduler -D
                    

                    如果您想尝试这种方法,我可能需要先备份您的数据,然后再执行任何操作。

                    【讨论】:

                      【解决方案19】:

                      有同样的问题,但最佳答案对我来说太长了,所以我建议打开另一个 shell 窗口类型 cd #enter 然后再试一次

                      【讨论】:

                        猜你喜欢
                        • 2011-12-01
                        • 2021-10-19
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-10-04
                        • 2011-11-10
                        • 2013-05-02
                        • 1970-01-01
                        相关资源
                        最近更新 更多