Issue: Migrations Applied but Fields Missing in PostgreSQL – django.db.utils.ProgrammingError
In my Django project, I added new fields (subscription_start
, subscription_end
, etc.) to a model in client/models.py
, generated migrations, and ensured they are tracked in Git.
My CI/CD pipeline builds Docker images for Django, PostgreSQL, and Nginx. After deployment, the Django container uses a bash -c
script in docker-compose.yml
to:
- Wait for PostgreSQL availability via
psql
- Run
python manage.py migrate
- Start the server
Problem:
Even though Django reports:
Operations to perform:
Apply all migrations: admin, auth, client, contenttypes, sessions
Running migrations:
No migrations to apply.
…when accessing the admin panel or running queries, I get this error:
django.db.utils.ProgrammingError: column client_client.subscription_end does not exist
This indicates the migration file is present, Django thinks it’s applied — but the actual DB schema doesn’t have the new columns
I’ve Tried:
- Migrations are committed (not ignored in
.gitignore
)
- Migration files exist (
/migrations/0001_initial.py
includes the new fields)
- Confirmed PostgreSQL is up and running with persistent volume
- Tried faking migrations to zero and reapplying:
python manage.py migrate client zero
python manage.py migrate
But the column is still missing in the actual PostgreSQL database table.
Setup Summary:
- Python 3.9 (Docker)
- PostgreSQL (Docker, volume persisted)
- Django run command in
docker-compose.yml
:
command: bash -c "python manage.py makemigrations client && python manage.py migrate client && python manage.py makemigrations ThreeD && python manage.py migrate ThreeD && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
"
Few things come to mind. First I would connect to the container where you have your django app and run showmigrations
command, if you do not see your app, maybe it is not in INSTALLED_APPS
in production? You can also check whether you are connecting to the databse you think you are using, add a user and check if it is added in postgres database, you could use dbshell
command.
On another note, I don’t think you should be running the makemessages
command in compose. At this point, all the migrations should already be in your codebase, also runserver
is for development, for production you should use e.g. uWSGI as the way of starting your project.
Thanks for replying,
yes I can see when I run showmigrations command,
I used
python manage.py dbshell
the output was same DB,
I cannot test that right now, but if the migration was applied, then reversed/faked and then tried to be applied again with different content, Django might not see it, as it stores applied migrations inside the special django_migrations
table. Django does not track the content, but the name of the migrations, so it sees that it already applied it, and that is why it does not apply it again. If there is a record of the migration from client inside django_migrations
table, then you have your answer. So next step would be to inspect this table on you production db.
I’ve opened client/migrations/0001_initial.py
and confirmed that the new fields (like subscription_start
, subscription_end
, etc.) are included in the migration file.
note:
If I delete the database entirely and recreate it from scratch, then run migrate
, everything works as expected and the schema is created correctly — including the new fields.
But obviously, I don’t want to rely on deleting the database every time. That’s not a sustainable or production-safe solution.
It seems like Django is out of sync with the database schema, possibly because the migration history is marked as “applied” in the django_migrations
table, even though the actual schema hasn’t been updated.
This aligns with my diagnosis. At some point, the initial migration for client app was applied, and then its content was changed, and Django was not able to detect it. Deleting the database also fixes the problem because it also deletes the django_migrations
table.
Once a migration has been applied on production database, next changes should be added as new, e.g. 0002_aded_some_fields.py
migrations, the already applied migrations should not be changed.
I suspect the problem you have is caused by the makemigrations
command used as part of start command in docker compose, it should not be there, only the migrate
and runserver
(or preferably the uWSGI method of starting the project).
This problem will not reapear every time, and you will not have to delete the database every time, Django can handle very complicated model changes, but it is important to use it how it was intended to be used.
same issue when I run:
python manage.py migrate && runserver 0.0.0.0:8000
I used runserver because my app still in staging phase.
Did you run it on the old database (the one with initial client migration in django_migrations
) or the new (clean) one?
I tried both, old one and new one.
If the problem is still present, I think you might have to describe it a bit more.
The original issue was caused by things I described earlier, and normally the proposed solution would fix the problem.
Although, if you can isolate the problem and make it reproducible (e.g. share a repository or snippets of code), I am sure it would be easier to help, as right now I don’t think there is anything more I can do.
1 Like
If you have, at any time, either edited or deleted a migration, the easiest solution is to drop and recreate the database and rerun the migrations. Otherwise, you’ll need to do some amount of manual work to bring things back into sync.
(It can be done, but it’s a whole lot easier to just drop the database and rerun the migrations.)
1 Like
I solved by creating virtual environment at local machine (you can use venv or dev depends for what u have), makemigrations command will run after add or remove any model (manually), and then edit bash script on production server to:
bash -c “python manage.py migrate && python manage.py runserver 0.0.0.0:8000”