If you have a long list of migrations, sometimes it can take a while to migrate
each of those files every time the project is reset or spun up by a new
developer. Thankfully, Ecto comes with mix tasks to dump and load a database
structure which will represent the state of the database up to a certain point
in time, not including content.
Schema dumping and loading is only supported by external binaries pg_dump and
mysqldump, which are used by the Postgres, MyXQL, and MySQL Ecto adapters (not
supported in MSSQL adapter).
For example:
20210101000000 - First Migration
20210201000000 - Second Migration
20210701000000 - Third Migration <-- we are here now. run `mix ecto.dump`We can "squash" the migrations up to the current day which will effectively fast-forward migrations to that structure. The Ecto Migrator will detect that the database is already migrated to the third migration, and so it begins there and migrates forward.
Let's add a new migration:
20210101000000 - First Migration
20210201000000 - Second Migration
20210701000000 - Third Migration <-- `structure.sql` represents up to here
20210801000000 - New Migration <-- This is where migrations will beginThe new migration will still run, but the first-through-third migrations will not need to be run since the structure already represents the changes applied by those migrations. At this point, you can safely delete the first, second, and third migration files or keep them for historical auditing.
Let's make this work:
- Run
mix ecto.dumpwhich will dump the current structure intopriv/repo/structure.sqlby default. Checkmix help ecto.dumpfor more options. - During project setup with an empty database, run
mix ecto.loadto loadstructure.sql. - Run
mix ecto.migrateto run any additional migrations created after the structure was dumped.
To simplify these actions into one command, we can leverage mix aliases:
# mix.exs
defp aliases do
[
"ecto.reset": ["ecto.drop", "ecto.setup"],
"ecto.setup": ["ecto.load", "ecto.migrate"],
# ...
]
endNow you can run mix ecto.setup and it will load the database structure and run
remaining migrations. Or, run mix ecto.reset and it will drop and run setup.
Of course, you can continue running mix ecto.migrate as you create them.