Django:尝试写入只读数据库

9

我刚刚创建了一个Django项目。

python manage.py startapp smartrecruitment

然后我运行了数据库同步操作

 python manage.py syncdb
 Operations to perform:
 Apply all migrations: admin, contenttypes, auth, sessions
 Running migrations:
   Applying contenttypes.0001_initial... OK
   Applying auth.0001_initial... OK
   Applying admin.0001_initial... OK
   Applying sessions.0001_initial... OK

我已经添加了超级用户,但是在浏览器中无法访问/admin。 我尝试执行以下命令来授予Apache权限,但没有成功。

sudo chown apache <folder_containing_db.sqlite3>
sudo chown apache db.sqlite3

你为什么在开发阶段使用Apache来运行项目?使用开发服务器更容易。 - Daniel Roseman
不是这样的,但我在使用Django 1.7时遇到了一些问题,所以想要在我的服务器上部署一个基本项目。 - Jon
@Jon 你为什么说数据库是“只读”的?“我无法在浏览器中访问 /admin”这个说法太模糊了。无法访问是指怎样的情况?在浏览器中出现错误吗?在 Apache 日志中出现错误吗?还是其他错误? - Louis
当我访问该URL时,出现“尝试写只读数据库”的错误。应该出现一个管理员部分的登录表单,但我得到的是一个显示该消息的错误页面。这与此问题非常相似... https://dev59.com/32Ei5IYBdhLWcg3wq93k - Jon
它与您链接的问题有何不同? - jfs
4个回答

19

更改项目目录和数据库文件的所有者为 www-data

chown www-data:www-data /home/username/Django    
chown www-data:www-data /home/username/Django/db.sqlite  

我不知道为什么有人给它点了踩。这个答案实际上帮助了我! - xyres
2
这不是一个好的做法。您的 www-data 用户在您的数据库上具有写权限(并且需要),以便它能够正常工作,但您还将其写权限授予了整个代码库,这绝对是不应该发生的。 - Thibaut

4
你确实遇到了用户/组权限问题:需要使用具有对您的数据库文件读/写访问权限的用户运行Web服务器(使用sqlite3时)。
更改整个项目的所有者和组是一个坏主意,因为它将使您的Web服务器用户可以写入您的代码库,这永远不是一个好的做法。
最好的方法是在生产环境中使用真正的数据库而不是sqlite,以避免这种情况的发生。

https://docs.djangoproject.com/en/1.9/ref/settings/#databases

如果您想继续使用SQLite:将SQLite文件放在项目存储库之外,并为其及包含目录提供正确的读写权限(例如,只有www-data可以写入,但是您需要以www-data身份运行Django命令)。
some_dir [your_user:your_group]
--- your_django_project [github_user:github_user]
--- another_dir [www-data:www-data]
    |--- db.sqlite3 [www-data:www-data]

你的Web服务器(apache / nginx)运行为www-data


你能否在这里添加一些示例代码?这更像是一个理论性的回答,无法完全解决问题。虽然已经听起来正确,但如果你能再加上一些代码就更完美了!谢谢! - cramopy
我已经编辑了我的回复,因为这只涉及到权限问题,所以没有代码。 - Thibaut

1

0
简而言之,当写入 SQLite 数据库的应用程序没有写入权限时会发生这种情况。
有三种解决方法:
  1. 使用 chown 授予 db.sqlite3 文件及其父目录(因此也可以进行写入访问)的所有权给用户(例如:chown username db.sqlite3
  2. 将 Web 服务器(通常为 Gunicorn)作为根用户运行(在运行 gunicorn 或 django 的 runserver 命令之前运行命令 sudo -i
  3. 通过运行命令 chmod 777 db.sqlite3 允许所有用户读取和写入(危险选项)
注意:除非您在本地机器上运行 Web 服务器或数据库中的数据对您来说根本不重要,否则永远不要选择第三个选项。

第二个选项也像@mateuszb所说的那样很危险。在Django中,由于Django是以这种方式设计的,代码注入的风险非常低。在Django中,只有当开发人员使用evalexec编写极易受攻击的代码时,才会发生整个操作系统被占领的情况。如果您对自己的代码质量不太自信,甚至不知道什么是代码注入,那么第二个选项就不适合您。

此外,如果您使用像mysql和Postgres这样的数据库,则不会出现此错误。Sqlite不适合高流量的Web服务器。


永远不要做第二个。你的代码中任何漏洞都会给黑客提供sudo权限。 - mateuszb
@mateuszb 我同意。你能给一个典型的例子吗? - Mohammed Shareef C
我不确定一个典型的代码注入是什么,但任何代码注入都可能导致整个操作系统被攻占,从而将内部网络置于危险之中。如果网站属于apache(如apache httpd的情况),那么黑客仅限于它拥有并能够编写的文件 - 这应该排除了它自己的代码。对这样的用户也只有有限的工具可用(没有ssh等)。 - mateuszb
@mateuszb 在 Django 中,代码注入的风险非常低,因为 Django 是以这样的方式设计的。在 Django 中,只有当开发人员使用 evalexec 编写极易受攻击的代码时,才会发生整个操作系统被占领的情况。 - Mohammed Shareef C

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