Phoenix application code and Ecto migration rollback: keeping schema and code in sync after schema changes
0 reputation · 12 Dec 2021, 09:44 UTC
0 reputation · 12 Dec 2021, 09:44 UTC
Goal: Ensure that after rolling back a migration, the deployed Phoenix application code remains compatible with the resulting database schema, avoiding missing columns or tables that the code expects.
Constraints: Ecto’s change/0 can automatically reverse only a subset of schema operations; dropping columns or tables loses data unless a compensating step is added, and execute/1 cannot be inverted automatically. The safety of a rollback also depends on whether the database supports transactional DDL and on the exact Ecto version in use.
Uncertainty: The project has not settled on whether to treat every migration as required to be reversible (using change/0 or explicit up/down) or to allow irreversible migrations and rely on manual restore procedures, and how to detect mismatches between code and schema after a rollback.
34775 reputation · 12 Dec 2021, 18:46 UTC
Enforce reversible migrations, add a CI check that validates the schema against the code after a rollback, and treat dropped columns/tables as either compensated or blocked until the dependent code is removed.
Adopt a rule that every migration must be reversible. Implement it with change/0 whenever possible; if a migration needs custom SQL or irreversible operations, provide an explicit up/0/down/0 pair that exactly inverses each step. Log any migration that cannot be expressed this way as a policy violation and block its merge.
Add a job that:
structure.sql into a temporary database (e.g., PostgreSQL Docker container).Ecto.Schema.field_info/2 for each field; any :error causes the task to exit non‑zero, indicating missing columns or tables.If any step fails, the build is rejected.
Two options:
down/0 function that raises if the dependent schema/module is still present, and document a manual restore procedure (e.g., backup restore or manual SQL).The team is unsure whether to treat all migrations as reversible or to allow irreversible steps and rely on manual recovery. Enforcing reversibility eliminates ambiguity and lets automated tooling detect mismatches early.
change/0 can automatically reverse only a subset of schema operations; custom SQL via execute/1 must be manually inverted.mix ecto.migrator.is_reversible?/1 on new migrations.mix ecto.rollback.After running mix ecto.rollback VERSION=n locally:
mix ecto.dump and diff the output against the committed structure.sql; zero differences confirm schema sync.Ecto.Schema.field_info/2 for all schema fields; a non‑zero exit signals missing columns.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.