Ubuntu服务器中的OperationalError: 尝试写入只读数据库

9
我正在使用mod_wsgiapache2在Ubuntu服务器上运行FlaskApp。我成功地在本地主机上运行了该Flask应用程序,然后将其部署到了Ubuntu服务器上。
但是,当我尝试更新数据库时,出现错误:
Failed to update model. (OperationalError) attempt to write a readonly database u'UPDATE mysongs SET songurl=? WHERE songid.id = ?' (u'www.site.com/I_wanna_dance', 1)

现在我尝试查找数据库文件的权限,它是:

-rwxr-xr-x 1 www-data www-data 10240 Jul 14 15:35 /var/www/mywebsite/appfolder/appdata.db`

当我尝试更改权限为777、755、644等时,它显示另一个错误:无法打开数据库文件。尽管在localhost上使用644权限的数据库文件工作正常,但在ubuntu服务器上却不行。
我还检查了目录的权限,对于/var /var/www /var/www/mywebsite /var/www/mywebsite/appfolder等,所有者用户名和组均为www-data:www-data
我尝试过搜索谷歌,但除了建议更改文件/目录权限之外,没有正确的解决方案。
为什么无法读取/访问数据库文件?
请提供建议。

你是否使用了 uid (http://uwsgi-docs.readthedocs.org/en/latest/Options.html#uid) 和 gid (http://uwsgi-docs.readthedocs.org/en/latest/Options.html#gid) 来运行 uwsgi?哪个用户启动了 uwsgi? - tbicr
您是否使用绝对路径来访问数据库文件?在 mod_wsgi 下,当前工作目录可能并非您认为的那样,因此相对路径会失效。如果您正在这样做,实际上它甚至无法找到数据库文件,但检查一下是值得的。还要确认 Web 应用程序进程确实正在以 www-data 身份运行。 - Graham Dumpleton
4个回答

8
这个问题与文件权限管理有关,主要与在Apache配置文件(*.conf)中选择的用户相关,该用户用于保存应用程序进程。简而言之:需要匹配此用户的写入权限
大多数情况下,sqlite数据库文件是由特定用户(例如当前用户)创建的,并且站点应用程序正在由Apache默认用户www-data启动的子进程中运行(如果在指令WSGIDaemonProcess中未指定user参数)。在这种情况下,可以读取数据库,但如果尝试修改任何内容,将会抛出以下错误:

(OperationalError) attempt to write a readonly database...

因为www-data对文件(或父文件夹)没有权限。

第一种方法:将权限应用于用户www-data

您可以在数据库文件及其父文件夹上设置写入权限。

如果文件夹包含其他文件,则可以添加写入权限,并仅将数据库文件的所有权更改为用户www-data,例如:

sudo chmod o+w db_directory
sudo chown www-data:  db_directory/site_database.db 

如果文件夹中只包含数据库文件,您可以尝试直接更改文件夹所有者:

sudo chown -R www-data: db_directory

然后检查读取/写入权限是否已经设置好(使用ls -l site_database.db命令)

此文章中提供更多帮助。


其他解决方案:添加特定用户来运行应用程序进程

可以通过在Apache配置文件的WSGIDaemonProcess指令中提供usergroup参数来实现此操作。这将使Apache在特定用户下启动子进程。

例如:

...
WSGIDaemonProcess main user=myuser group=myuser threads=3 python-home=/path/to/the/virtualenv/
WSGIProcessGroup main
WSGIApplicationGroup %{GLOBAL}
...

这个用户将管理所有操作,包括对任何文件的读写,因此请检查其在每个相关文件上是否具有所需的权限。
出于安全考虑,您可能不应使用广泛特权的用户。
一些评论可以在this post中提供帮助。
注意:如果您使用像Apache配置中的ErrorLog指令来管理自己的日志文件,则需要小心,这些文件将遵循相同的权限逻辑。对于任何可能被应用程序更改的文件也是如此。

2
对于SQLite,您还需要将数据库所在的目录对代码运行的用户可写,否则它无法创建数据库锁定文件。因此,仅更改数据库文件的所有权是不够的。 - Graham Dumpleton
我已经运行了这个方法,但它仍然无法正常工作。我可能做错了什么?db文件夹权限显示为drwxr-xr-x 2 www-data www-data。我还在db文件本身上运行了666权限,并显示如下:`getfacl users.db

file: users.db

owner: www-data

group: www-data

user::rw- group::rw- other::rw-`
- erixliechtenstein
具体的用户解决方案和链接非常有帮助。谢谢。 - BalooRM

2

问题已解决。这是由于数据库文件权限冲突引起的。


18
你能否更新你的问题并附上你的解决方案,以便未来在 Stack Overflow 上搜索的人可以看到你做了什么? - David Hagan
3
修复:您需要在系统中找到数据库文件并允许写入权限。(例如,授予所有人Git访问权限:sudo chmod a+w file.db) - mulya
你需要给www-data用户授予你的项目和数据库权限,详见我的答案。 - Diego Bianchi
如果您可以提供有关解决方案的详细说明,那么这个答案可能会很有用。 - dlewin
此答案缺乏细节,请考虑添加您的解决方案的详细信息。 - BalooRM

2

只需将www-data赋予您的项目和数据库权限即可。

sudo chown www-data:www-data ProjectPath

sudo chown www-data:www-data dbPath

我正在使用 AWS EC2 实例工作,出现了同样的错误。感谢您的回复。 - Aakash Yadav

-1

在 Windows 2008 服务器 / IIS 7.5 上托管 Django Rest Framework 时遇到了此问题。在本地主机上运行正常。我添加了新功能以处理文件上传特性以及“文件名”。文件已成功上传,但数据库似乎无法接受“文件名”字符串中的文本。

解决方案: 进入您的相关数据库。(如果您没有分配任何特定的数据库,请考虑基础文件夹中的 db.sqlite3 文件)

右键单击 db.sqlite3 --> 属性 --> 安全 --> 编辑 --> 添加

在文本框中输入Everyone --> Checkname --> 确定

刷新 IIS 上的服务器并尝试运行应用程序。


这个问题不是针对Windows的,而是针对Ubuntu的。 - User

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接