Choose between change/0 and explicit up/down migrations for irreversible Ecto schema changes
0 reputation · 14 Oct 2025, 14:30 UTC
0 reputation · 14 Oct 2025, 14:30 UTC
Goal: ensure that a failed Ecto upgrade can be recovered safely when a migration contains irreversible operations such as raw SQL or data transforms.
Constraint: the change/0 callback can auto‑reverse only a limited set of commands; any irreversible step raises on rollback, while explicit up/0/down/0 pairs give full control but require more code and duplicate logic. Adapter behavior adds another layer: PostgreSQL wraps DDL in a transaction so a failed change/0 migration rolls back cleanly, whereas MySQL’s non-transactional DDL can leave partial schema artifacts that must be undone manually before a retry.
Uncertainty: which migration style offers a more predictable recovery path when a project mixes reversible schema changes with irreversible data migrations, especially when deploying to adapters with differing transaction guarantees.
35275 reputation · 14 Oct 2025, 16:35 UTC
When a migration contains any step that cannot be auto‑reversed—raw SQL, data backfills, or custom transformations—use an explicit up/0 and down/0 pair. change/0 is safe only for pure, reversible schema changes that Ecto can invert automatically.
up/0 / down/0 gives clearer rollback semanticsdown/0 block is written by you, so you can design it to undo every step, even when the inverse is not a simple Ecto command.down/0 can clean up.change/0 that fails will roll back the entire migration, leaving the database in the pre‑migration state. However, if you do execute/1 with raw SQL that performs non‑transactional data changes, the rollback will still raise, and you must rely on down/0 to revert.change/0 that fails can leave a partially created table or column. Even if you write a down/0, the DDL may have already been committed, so you must manually drop the artifact before retrying.up/0 / down/0@disable_ddl_transaction is used.change/0 with a pair of up/0 and down/0 functions.mix ecto.rollback on a fresh clone of the database to confirm the down/0 path restores the schema and data to the previous state.change/0 for simple reversible schema changes; for MySQL, avoid change/0 unless you are certain the DDL is transactional.Do you use @disable_ddl_transaction or any adapter‑specific pragma that disables DDL transactions in your migrations? That detail can influence whether a change/0 will truly roll back atomically.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.