Collapsing Ecto Migrations

Moxley Stratton
2 min readNov 27, 2019

--

A migration file that no longer provides value as a distinct migration is just dead weight. It’s a liability. When an application reaches a year or two in age, the list of database migrations in its history can grow to an impressive size. Sometimes, changes to an application will cause migrations from the past to fail. When a new developer onboards the application, they can get blocked by these bugs.

What if there was a way to flatten all old migrations into a single database schema? There is.

priv/repo/migrations/20191018120000_initial_schema.exs

Here’s how to do it:

  1. Pick the most recent migration that is deployed to production. Delete all the migrations before it.
  2. Get a schema dump of the production database, with no data. Just the schema. Save it to /priv/repo/initial_schema.sql. For PostgreSQL, that might look something like this: pg_dump my_database --schema-only --no-owner --exclude-table=schema_migrations > schema.sql
  3. Rename the latest migration file and module name. Keep the timestamp in the filename, but rename the rest to something like “_initial_schema.exs”. Similarly, rename the module.
  4. Replace the body of the module with the module body shown above.
  5. Remove all migration files that came prior to this migration.
  6. Test it in the test environment: MIX_ENV=test mix do ecto.drop, ecto.create, ecto.migrate. Then mix test.

The modified migration calls out to psql, and passes the same connection parameters that the application’s Repo module uses. The schema dump is imported into the database via psql. This works for PostgreSQL. If you’re using another database, replace the psql command with the command that is provided by your database.

--

--