Django: Attempt to write a read-only database

2019-06-28 06:08发布

问题:

I have just created a Django project with

python manage.py startapp smartrecruitment

I then ran a db sync

 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

And added my superuser, but I cannot access /admin in the browser. I have tried doing the following commands to give apache permissions, but have had no luck.

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

回答1:

change owner of the project directory and database file www-data

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


回答2:

You have indeed user/group permission problems : you need to run your webserver with a user who has read / write access to your db file (when using sqlite3)

Changing the owner and the group of your entire project is a bad idea since it would allow your web server user to write on your codebase, which is never a good practice.

A better idea is to use a real database in production instead of sqlite to avoid this.

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

If you want to stick with sqlite : place your sqlite file outside of your project repository and give it and the containing directory correct read/write accesses (for instance only www-data can write, but then you need to run your django commands as www-data)

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]

And your webserver (apache / nginx ) runs as www-data



回答3:

I was looking for the solution, as I followed CentOS tutorial by this link. https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-with-apache-and-mod_wsgi-on-centos-7

Here is the permission for that tutorial,

sudo usermod -a -G root apache
chmod 710 /root/myproject
chown apache:apache /root/myproject
chown apache:apache /root/myproject/db.sqlite


回答4:

In short, it happens when the application which writes to the sqlite database does not have write permission.

This can be solved in three ways:

  1. Granting ownership of db.sqlite3 file and its parent directory (thereby write access also) to the user using chown (Eg: chown username db.sqlite3 )
  2. Running the webserver (often gunicorn) as root user (run the command sudo -i before you run gunicorn or django runserver)
  3. Allowing read and write access to all users by running command chmod 777 db.sqlite3 (Dangerous option)

Note: Never go for the third option unless you are running the webserver in a local machine or the data in the database is not at all important for you.

Second option is also dangerous as @mateuszb said. Risk of code injection is very low in Django since Django is designed in such a way. In Django, capture of entire OS can happen only if the developer writes horribly vulnerable code using eval or exec. If you are not confident about your code quality or even don't know what code injection is, second option is not for you.

Moreover, this error does not occur if you are using a database like mysql and Postgres. Sqlite is not a good option for a webserver with a high traffic.