Debugging Alembic: the revision graph and the data it meets
A migration bug is a deployment bug: it shows up at the worst moment, on the machine you cannot experiment on. The skill this section trains is bringing the failure back to your own machine by reproducing the exact starting state the migration ran on.
Alembic revisions are a graph, not a list
Each revision names its parent in down_revision. File names, dates and the order in which people merged branches mean nothing. Two revisions with the same parent are two heads, and alembic upgrade head refuses to choose. Learn to read the graph with alembic heads and alembic history, and to fix a fork with a merge revision (down_revision is a tuple of both heads) instead of deleting files that may already have been applied elsewhere.
A migration is a function of the schema and the data
A migration can pass on an empty database and on a freshly built staging database, and still fail on production, because production has rows. Adding a NOT NULL column with no default, creating a unique index over duplicates, changing a type over legacy values: all of these only fail when there is data. To debug one, bring a scratch database to the revision before the failing one (alembic upgrade <revision>), insert rows shaped like production, then upgrade forward and read the real error.
The usual fix is expand, backfill, constrain: add the column in a form existing rows can satisfy (nullable or with a server default), fill it, then tighten it.