How to Fix Django Migrations Not Applying
In this tutorial, you'll learn about How to Fix Django Migrations Not Applying. We cover key concepts, practical examples, and best practices.
The Problem
You run python manage.py migrate and see No migrations to apply even though the database tables don't exist. Or you get django.db.migrations.exceptions.InconsistentMigrationHistory with conflicting migration states. Django's migration tracker table (django_migrations) thinks migrations are applied when they aren't, or has conflicting entries. This typically happens after restoring a database dump, switching branches with different migrations, or merging conflicting migration files.
Quick Fix
1. Check current migration state
python manage.py showmigrations
Expected output:
myapp
[X] 0001_initial
[ ] 0002_add_age_field
[ ] 0003_add_email_field
[X] means applied, [ ] means pending.
2. Fake-apply a migration (mark it as applied without running SQL)
python manage.py migrate myapp --fake
Use this when the database schema already matches the migration but Django's tracker disagrees. For example, after restoring a database backup.
3. Fake an individual migration
python manage.py migrate myapp 0002 --fake
This marks migration 0002 (and all before it) as applied without running any SQL. Useful after manually creating a table or restoring from a dump.
4. Un-apply a migration that shows as applied but isn't
python manage.py migrate myapp zero --fake
This marks all migrations for myapp as unapplied in the tracker without touching the database. Then run migrate normally:
python manage.py migrate myapp
5. Resolve InconsistentMigrationHistory
# Check which migrations conflict
python manage.py showmigrations
# Fake the dependency migration first
python manage.py migrate other_app 0003 --fake
# Then run the migration that was blocked
python manage.py migrate myapp
This error happens when a migration depends on another that hasn't been applied yet. Faking the dependency resolves it.
6. Rebuild migrations from scratch (last resort)
# Backup your database first!
python manage.py migrate myapp zero
rm myapp/migrations/0*.py
python manage.py makemigrations myapp
python manage.py migrate myapp
Only do this in development. On production, always use --fake to align the migration state.
7. Merge conflicting migration files
# If two branches both created migration files with the same number
python manage.py makemigrations --merge
This creates a new migration that depends on both conflicting migrations, resolving the conflict without losing any changes.
8. Check the django_migrations table directly
-- Connect to your database and inspect
SELECT app, name, applied FROM django_migrations ORDER BY app, name;
Expected output:
app | name | applied
--------+-------------------------+------------------------
myapp | 0001_initial | 2025-06-23 10:30:00+00
myapp | 0002_add_age_field | 2025-06-23 10:31:00+00
This shows exactly which migrations Django believes are applied. If a migration is listed here but the corresponding table doesn't exist, you need to fake-apply or manually create the table.
Prevention
- Commit migration files to version control with every model change
- Never delete migration files that have been applied on production
- Use
python manage.py makemigrations --dry-runto preview changes - Run
showmigrationsbefore and after anymigratecommand - Pull the latest migrations before creating new ones to avoid numbering conflicts
- Keep a single source of truth for migration history across the team
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro