Table of Contents
Introduction
Django migrations are essential for database schema management, but they can become problematic when multiple engineers work on the same application simultaneously. One common issue is migration sequence conflicts — when two engineers create migrations with the same sequence number, causing Django to throw exceptions during deployment.
This guide shows you how to resolve these conflicts safely, without affecting production data or breaking your deployment pipeline.
Understanding the Problem
Migration sequence conflicts occur when:
- Engineer A creates migration
0002_some_migrations.py
and pushes to production - Engineer B (working locally) creates migration
0002_some_other_migrations.py
- When Engineer B pulls the latest changes, Django encounters conflicting sequence numbers
- Django throws an exception because it can't determine the correct migration order

The key constraint: You cannot modify or remove the production migration because it's already applied and users depend on it.
Why Squashing Won't Help
Migration squashing is a Django feature that combines multiple migration files into one. However, it won’t solve this specific problem because:
- Production migration is live: Squashing would require removing a live migration, which isn't feasible.
- Data dependencies: Squashing might roll back schema changes or data, risking data loss.
- Deployment timeline: You can't squash and coordinate across environments quickly during an active issue.
- Team coordination: Squashing resets migration state for everyone — highly disruptive in active development.
Use squashing for long-term cleanup, not for resolving active sequence conflicts.
Step-by-Step Solution
Step 1: Revert Your Local Migration
python manage.py migrate app_name 0001_initial
This rolls back your local conflicting migration.
Step 2: Remove Your Local Migration File
rm app_name/migrations/0002_some_other_migrations.py
Step 3: Keep the Production Migration
Ensure the 0002_some_migrations.py
from the main branch is kept — it's already applied in production.
Step 4: Create a New Migration
python manage.py makemigrations app_name
This will generate 0003_some_other_migrations.py
with the correct sequence number.
Step 5: Apply the New Migration
python manage.py migrate app_name
Step 6: Push Your Changes
git add .
git commit -m "Recreate migration with correct sequence number"
git push origin main
Prevention Strategies
1. Coordinate Migration Creation
- Communicate with team before creating migrations
- Use feature branches and pull requests
- Add clear migration prefixes if needed
2. Add Migration Checks in CI
# .github/workflows/migration-test.yml
- name: Test Migrations
run: |
python manage.py makemigrations --check
python manage.py migrate --plan
3. Periodic Squashing
python manage.py squashmigrations app_name 0001 0010
This helps reduce migration clutter over time.
4. Always Backup Before Migrations
pg_dump database_name > backup_$(date +%Y%m%d_%H%M%S).sql
Never run migrations on production without a backup.
Conclusion
Migration sequence conflicts are inevitable in active teams. But by following a clear recovery process:
- Production stability is maintained
- No data is lost
- Your team keeps moving forward
- Migration history stays clean and traceable
Pro tip: Test all migrations in a staging environment before promoting to production.