将 SQLite 数据库模式更改为读写

如何将 SQLite 数据库从只读更改为读写?

当我执行 update 语句时,我总是得到:

SQL 错误: 尝试写入只读数据库

SQLite 文件是文件系统上的可写文件。

206675 次浏览

出现此错误消息可能有以下几个原因:

  • 几个进程同时打开数据库(请参阅常见问题解答)。

  • 有一个插件压缩和加密数据库。它不允许修改数据库。

  • 最后,另一个常见问题说: “确保包含数据库文件的目录对于执行 CGI 脚本的用户也是可写的。”我认为这是因为引擎需要在目录中创建更多的文件。

  • 整个文件系统可能是只读的,例如在崩溃之后。

  • 在 Unix 系统上,另一个进程可以替换整个文件。

我今天也有这个问题。

它是由 Windows Mobile 上的 ActiveSync 引起的-我工作的文件夹被同步了,所以 AS 进程不时地抓取数据库文件导致了这个错误。

如果使用 Android。

确保您已经将写入 EXTERNAL_STORAGE的权限添加到 AndroidManifest.xml

将这一行添加到 <application>标记上方和外部的 AndroidManifest.xml文件中。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

这将允许您的应用程序写入 sdcard。如果您的 EXTERNAL_STORAGE是您在设备上存储数据库的位置,这将有所帮助。

当一个应用程序已经访问了您的数据库,并且您正试图用另一个应用程序访问它时,通常会发生此错误。

我解决这个问题的方法是把数据库文件夹中所有文件的所有者从“ root”改为我自己的用户。

只要对所述文件夹执行 ls -l操作,如果任何文件属于 root,只需将其更改为您的用户,如:

# For each file do:
sudo chown "$USER":"$USER" /path/to/my-folder/file.txt


# Or "R"ecursive.
sudo chown -R "$USER":"$USER" /path/to/my-folder

在 Linux 命令行 shell 中,我这样做了:

chmod 777 <db_folder>

其中包含数据库文件。

现在我可以访问我的数据库并进行插入查询了。

在 Linux 上,为包含数据库文件的整个文件夹授予读/写权限。

另外,SELinux 可能会阻塞写入。您需要设置正确的权限。

在我的 SELinux Management GUI (在 Fedora 19上)中,我选中了标签为 HTTPD _ united (统一 HTTPD 处理所有内容文件)的行上的复选框,然后就可以开始了。

在 Ubuntu 上,将所有者更改为 Apache 组并授予正确的权限(不,不是777) :

sudo chgrp www-data <path to db.sqlite3>
sudo chmod 664 <path to db.sqlite3>

更新

您还可以设置 小组使用者的权限。

sudo chown www-data:www-data <path to db.sqlite3>

在 Windows 上:

Dr: 再次打开该文件。

我们的系统正在遭受这个问题,它肯定不是一个权限问题,因为程序本身可以打开数据库作为可写的许多线程的大多数时间,但偶尔(只有在 Windows 上,而不是在 OSX 上) ,一个线程会得到这些错误,即使所有其他线程在程序没有困难。

我们最终发现,失败的线程只是那些在另一个线程关闭数据库后立即试图打开数据库的线程(在3毫秒内)。我们推测这个问题是由于 Windows (或者 Windows 下的 sqlite 实现)并不总是在关闭文件时立即清理文件资源。我们通过在打开数据库时对其运行一个测试写查询(例如,创建然后删除一个名称愚蠢的表)来解决这个问题。如果创建/删除失败,我们将等待50毫秒并再次尝试,重复直到成功或经过5秒钟。

它起作用了; 显然,只需要有足够的时间将资源清空到磁盘。

(此错误消息通常具有误导性,并且通常是一般权限错误)

在视窗上

  • 如果您直接针对数据库发出 SQL,请确保您正在使用的运行 SQL 的应用程序以管理员身份运行
  • 如果应用程序正在尝试更新,则它用于访问数据库的帐户可能需要对包含数据库文件的文件夹的权限。例如,如果 IIS 正在访问数据库,IUSR 和 IIS _ IUSRS 可能都需要适当的权限(您可以尝试这样做,暂时让这些帐户完全控制文件夹,检查这是否有效,然后绑定适当的权限)

为了分享个人经验,我遇到了这个错误,最终修复两者。可能不一定与你的问题有关,但似乎这个错误是如此普遍,它可以归因于无数的事情。

  1. 在另一个应用程序中打开数据库实例。我的数据库似乎一直处于“锁定”状态,所以它过渡到只读模式。我能够通过停止共享数据库的应用程序的第二个实例来跟踪它。

  2. 目录树权限-请确保用户帐户不仅在文件级别有权限,而且在整个上层目录级别到/级别都有权限。

谢谢

我在 ESP32上使用 SQLite,这里的所有答案都是“非常奇怪”... ..。 当我查看 ESP 闪存上的数据时,我注意到整个数据库只有一个文件(还有一个临时文件)。

在这个 db 文件中,我们当然有用户表,但也有系统表,例如“ sqlite _ master”,它包含表的定义。 因此,似乎很难相信这是一个“ chmod”问题,因为如果文件是只读的,甚至创建表也是不可能的,因为 SQLite 将无法写入“ SQLite _ master”数据..。 因此,我认为我们的朋友 user143482正试图访问一个“只读”表。在 SQLite 源代码中,我们可以看到一个名为 tabIsReadOnly 的函数,其注释如下:

 /* Return true if table pTab is read-only.
**
** A table is read-only if any of the following are true:
**
**   1) It is a virtual table and no implementation of the xUpdate method
**      has been provided
**
**   2) It is a system table (i.e. sqlite_master), this call is not
**      part of a nested parse and writable_schema pragma has not
**      been specified
**
**   3) The table is a shadow table, the database    connection is in
**      defensive mode, and the current sqlite3_prepare()
**      is for a top-level SQL statement.
*/

在 win10系统崩溃后,尝试用 DB 浏览器打开 DB,但只读。 只需删除日志文件。

如果 <db_name>.sqlite-journal文件与 DB 文件存在于同一个文件夹中,这意味着您的 DB 当前打开,并且正在进行一些更改(或者在复制 DB 文件夹时已经打开)。如果您尝试打开数据库在这个时候错误 attempt to write a readonly database(或类似)可能会出现。

作为一个解决方案,等到 <db_name>.sqlite-journal消失或删除它(不推荐在工作系统上使用)