How I can reorder migrations execution in umbrella apps?

I created an umbrella app as a template for a workshop I’ll give into my university. So I preferred to show an umbrella project to build many APIs projects that communicate between them. So each app has it own Ecto.Repo and also its migrations path/files.

However it seems that migrations are runned in the order of app creation/disposition on the apps directory.

This is the current structure of my apps:

.
├── Dockerfile
├── README.md
├── apps
│   ├── liquid_accounts
│   ├── liquid_auth
│   ├── liquid_operations
│   ├── proxy_web
│   └── release
├── config
│   ├── config.exs
│   ├── dev.exs
│   ├── prod.exs
│   ├── runtime.exs
│   └── test.exs
├── docker-compose.yml
├── flake.lock
├── flake.nix
├── mix.exs
├── mix.lock
└── rel

When I trying to run migrations (2 from liquid_auth and 1 for liquid_accounts), that occurs:

The database for Liquid.Accounts.Repo has been dropped
The database for Liquid.Auth.Repo has already been dropped
The database for Liquid.Operations.Repo has already been dropped
The database for Liquid.Accounts.Repo has been created
The database for Liquid.Auth.Repo has already been created
The database for Liquid.Operations.Repo has already been created

21:24:25.695 [info] == Running 20231020225840 Liquid.Accounts.Repo.Migrations.CreateBankAccount.change/0 forward

21:24:25.697 [info] create table bank_account
** (Postgrex.Error) ERROR 42P01 (undefined_table) relation "user" does not exist
    (ecto_sql 3.10.2) lib/ecto/adapters/sql.ex:1047: Ecto.Adapters.SQL.raise_sql_call_error/1
    (elixir 1.15.7) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (ecto_sql 3.10.2) lib/ecto/adapters/sql.ex:1154: Ecto.Adapters.SQL.execute_ddl/4
    (ecto_sql 3.10.2) lib/ecto/migration/runner.ex:327: Ecto.Migration.Runner.log_and_execute_ddl/3
    (elixir 1.15.7) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (ecto_sql 3.10.2) lib/ecto/migration/runner.ex:290: Ecto.Migration.Runner.perform_operation/3
    (stdlib 5.1.1) timer.erl:270: :timer.tc/2
    (ecto_sql 3.10.2) lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/8

Of course relation “user” doesn’t exist! It is defined on liquid_auth app, which it should be the first one migrated as those migrations were the first ones I created…

Migrations of liquid_auth:

20231020160450_create_user.exs		20231020173651_create_api_key.exs

And the only migration for liquid_accounts: 20231020225840_create_bank_account.exs.

So how can I reorder the migrations execution order?

I‘d argue that a single db should be handled by a single set of migrations. And if you don‘t follow that advice then you want to avoid dependencies between the separate systems. That can be done e.g. using namespacing of global things like tables.

One could argue that migrations should run in order of the dependency tree between the applications, but not sure if ecto does/could have access to that.

Edit: Maybe you can already customize the oder with the ecto_repos configuration.

2 Likes