u/chirag45610

▲ 0 r/django

Django migrate keeps failing in CI with duplicate column/table errors — so I wrote a self-healing wrapper that detects the failing migration, fakes it, and retries

If you've run Django migrations on MySQL in CI long enough, you've seen this:

django.db.utils.OperationalError: (1060, "Duplicate column name 'some_field'")

Schema drift between environments, a migration applied manually, a botched rollback — whatever the cause, the pipeline is now broken and someone has to SSH in, figure out which migration to fake, run it manually, and retry.

I got tired of doing that so I wrote a wrapper around manage.py migrate that handles it automatically.

What it does:

Runs migrate normally

If it hits a duplicate column/table/key error (MySQL 1050, 1060, 1061, 1068, 1091) — parses the output to identify the failing migration, fakes it, and retries

If it hits InconsistentMigrationHistory — deletes the offending record from django_migrations and retries

Any other error — stops immediately so you don't mask real problems

Loops until all migrations are applied successfully or an unhandled error stops it

What it doesn't do:

Won't blindly fake everything — only fakes the specific migration that caused the error

Won't swallow unrecognised errors

MySQL only — relies on MySQL error codes

https://github.com/chiragJoshi24/Django-AutoMigrate/

Curious if others have hit this — how are you handling migration drift in CI?

reddit.com
u/chirag45610 — 2 days ago
▲ 0 r/django

Django migrations were blocking our writes on 50M+ row tables — so I built a schema sync tool that skips them entirely

At work we run Django on MySQL at ~900 req/s, and Django migrations became a real pain point:

ALTER TABLE on large tables acquires full locks — we've had deploys block writes for minutes Migration history gets messy across environments No easy way to preview what DDL will actually run before committing to it Rolling back a bad migration on a 50M+ row table isn't fun

So I wrote a ~400 line Python script that diffs your Django models against the live DB schema using INFORMATION_SCHEMA and generates only the minimal ALTER TABLE statements needed. No migration files, no migration history table, no makemigrations/migrate dance. What it does:

Compares every model field against the actual DB columns (type, nullability) Adds missing columns, drops removed ones, modifies changed types Handles GeneratedField (MySQL virtual/stored columns) Drops FK constraints before modifying dependent columns (avoids MySQL errors) Syncs indexes: db_index, unique, Meta.indexes, unique_together Dry-run mode (--dry-run) to preview the exact SQL before touching anything Skip list for apps you manage manually (Wagtail, CMS, etc.)

What it doesn't do (intentionally):

No data migrations — schema-only No migration history tracking — it's idempotent, run it anytime No Postgres/SQLite support — MySQL-specific INFORMATION_SCHEMA queries No rename detection — a rename looks like a drop + add

Example dry-run output: ALTER TABLE users_profile ADD COLUMN last_active DATETIME NULL; ALTER TABLE orders DROP COLUMN legacy_status; ALTER TABLE products MODIFY COLUMN price DECIMAL(12,2) NOT NULL;

https://github.com/chiragJoshi24/Django-Migrate-Lite

Would love feedback — especially if you've dealt with similar migration pain at scale. Is this something others would find useful as a pip-installable package?

reddit.com
u/chirag45610 — 2 days ago