Steps to Troubleshoot "django.db.utils.ProgrammingError: permission denied for relation django_migrations"

PythonDjangoApachePostgresqlGithub

Python Problem Overview


What are some basic steps for troubleshooting and narrowing down the cause for the "django.db.utils.ProgrammingError: permission denied for relation django_migrations" error from Django?

I'm getting this message after what was initially a stable production server but has since had some changes to several aspects of Django, Postgres, Apache, and a pull from Github. In addition, it has been some time since those changes were made and I don't recall or can't track every change that may be causing the problem.

I get the message when I run python manage.py runserver or any other python manage.py ... command except python manage.py check, which states the system is good.

Python Solutions


Solution 1 - Python

I was able to solve my issue based on instructions from this question. Basically, postgres privileges needed to be re-granted to the db user. In my case, that was the user I had setup in the virtual environment settings file. Run the following from the commandline (or within postgres) where mydatabase and dbuser should be your own database and user names:

psql mydatabase -c "GRANT ALL ON ALL TABLES IN SCHEMA public to dbuser;"
psql mydatabase -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to dbuser;"
psql mydatabase -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to dbuser;"

Solution 2 - Python

As mentioned by @user3062149, this is likely caused by attempting to migrate a database table for which Django's psycopg2 user is not the table owner. For instance, if you have in your project's settings.py

DATABASES = {
    'default': {
        'USER': 'my_username',
        # ...

You will need to check that the table involved in the Django migration is owned by my_username. To do this in psql, you can use SELECT * FROM pg_tables ORDER BY tableowner;. This uses the view pg_tables, which "provides access to useful information about each table in the database." pg_tables is a part of Postgres' system catalogs, the place where a relational database management system stores schema metadata.

Say that the table in question is owned by other_username (not my_username).

To update the owner, you then need to call psql with --username=other_username, then change the owner:

ALTER TABLE public.<table_name> OWNER TO my_username;

Solution 3 - Python

If you receive this error and are using the Heroku hosting platform its quite possible that you are trying to write to a Hobby level database which has a limited number of rows.

Heroku will allow you to pg:push the database even if you exceed the limits, but it will be read-only so any modifications to content won't be processed and will throw this error.

Solution 4 - Python

For people still having issues using PostgresQL, I realized I needed to update schema public for each database I was connecting to. I had a dev and a staging database I was trying to use the same user for in my case.

Each database has it's own public schema. It's just a namespace in the database. If you're trying to use the user for another database, then you need to connect to each database you want to grant privileges to, and run your GRANT commands there. When you connect with a session, it's connecting to a particular database, and the GRANT commands only apply to that particular database.

RDS might look like this: enter image description here The DB session .. say

psql -U postgres -h some.host.com -p 5432 --password db_name
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myuser;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO myuser;

will only apply to DB name you connected to (say, db green arrow goes to, not the other). If you want to have the user work with Django for something OTHER than db_name, then you need to connect to that database and grant prileges on the public schema there too.

\c other_db

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myuser;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO myuser;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3062149View Question on Stackoverflow
Solution 1 - Pythonuser3062149View Answer on Stackoverflow
Solution 2 - PythonBrad SolomonView Answer on Stackoverflow
Solution 3 - PythonPete DermottView Answer on Stackoverflow
Solution 4 - PythonNick BradyView Answer on Stackoverflow