Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for pending Django migrations

In Django, is there an easy way to check whether all database migrations have been run? I've found manage.py migrate --list, which gives me the information I want, but the format isn't very machine readable.

For context: I have a script that shouldn't start running until the database has been migrated. For various reasons, it would be tricky to send a signal from the process that's running the migrations. So I'd like to have my script periodically check the database to see if all the migrations have run.

like image 831
Moss Collum Avatar asked Aug 05 '15 17:08

Moss Collum


People also ask

How can I see pending migrations in Django?

You can use it in python script with call_command and develop a way to check for the expected output. If there are any pending makemigrations of migrate calls, the output will be different from the expected and you can understand that something is missing. I'm running this at a CI/CD pipeline with very good results.

How can I see unapplied migrations in Django?

You have unapplied migrations; your app may not work properly until they are applied. Run 'python manage.py migrate' to apply them. How can I find out which migrations are unapplied without running migrate? One way to do this is to look at the django_migrations table in the DB and check which ones are applied.

How do I test migrations in Django?

django-test-migrationsSet some migration as a starting point. Create some model's data that you want to test. Run the new migration that you are testing. Assert the results!

How does Django know which migrations to run?

As a part of the answer to the question "how does Django know what migrations have been run?", they store records of applied migrations in the database! If you want to have a peek at what they store in the database, take a gander at the following using the Django shell.


2 Answers

Shell

The only simple solution I've found so far is running

./manage.py showmigrations | grep '\[ \]' 

which will output an empty string in case all migrations have been applied.

However, it is closely tied to the output format.

Python

I checked the source code of migrate command and it seems like this should do the trick:

from django.db.migrations.executor import MigrationExecutor from django.db import connections, DEFAULT_DB_ALIAS   def is_database_synchronized(database):     connection = connections[database]     connection.prepare_database()     executor = MigrationExecutor(connection)     targets = executor.loader.graph.leaf_nodes()     return not executor.migration_plan(targets)  # Usage example. if is_database_synchronized(DEFAULT_DB_ALIAS):     # All migrations have been applied.     pass else:     # Unapplied migrations found.     pass 
like image 141
Ernest Ten Avatar answered Oct 05 '22 10:10

Ernest Ten


1.10 release notes:

The new makemigrations --check option makes the command exit with a non-zero status when model changes without migrations are detected.

If you don't want to create the migrations, combine it with --dry-run:

python manage.py makemigrations --check --dry-run 

Note that this doesn't check whether the migrations were applied, it only checks whether the migration files were created.

like image 40
minusf Avatar answered Oct 05 '22 09:10

minusf