I’ve been bitten a few times by migrations that look reversible but aren’t —
RunPython without reverse_code, AlterField where rolling back silently does
the wrong thing, that sort of thing.
Built pytest-mrt to catch these before they hit production. For Django it does
static analysis of migration files — no database needed, just point it at a
migrations directory:
pip install pytest-mrt
mrt check yourapp/migrations/
It checks 30 patterns: missing reverse_sql/reverse_code on RunSQL/RunPython,
RemoveField without a compensating AddField in the reverse, type changes without
a reverse AlterField, no-op reverse functions, and a handful of others that are
easy to miss in review.
Runs in under 100ms on a typical project, so it fits comfortably in pre-commit
or CI as a blocking check.
Dynamic verification (actually running migrate --backwards against a real database
and asserting rows survived) is on the roadmap. The Alembic side already has this;
Django is next.
Would be interested to hear if anyone has patterns they’ve been burned by that
aren’t on the list. The patterns page has the full breakdown: