DEV Community

Daniel Franklin
Daniel Franklin

Posted on

Multiple Ecto Repos in one Phoenix application

I recently wanted to use multiple repos in one Phoenix application. I ran into Geoffrey Lessel's excellent guide from 2016 that worked well.

However, I found it annoying that mix ecto.reset didn't accept the option -r to specify which Repo to target like the other mix commands (for example, mix ecto.migrate -r MyApp.MyOtherRepo). I browsed through the mix folder of Ecto's source code, but I couldn't find where the reset command was defined. At this point I remembered that some mix commands are just shortcuts to existing commands defined in your mix.exs. I hadn't defined any, but mix phx.new had.

At the bottom of my mix.exs, I saw

# Aliases are shortcuts or tasks specific to the current project.
# For example, to install project dependencies and perform other setup tasks, run:
#
#     $ mix setup
# See the documentation for `Mix` for more info on aliases.
defp aliases do
    [
        setup: ["deps.get", "ecto.setup", "cmd npm install --prefix assets"],
        "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
        "ecto.reset": ["ecto.drop", "ecto.setup"],
        test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]
    ]
end
Enter fullscreen mode Exit fullscreen mode

To fix the issue, I modified the commands so they also worked on my other Repo.

# Aliases are shortcuts or tasks specific to the current project.
# For example, to install project dependencies and perform other setup tasks, run:
#
#     $ mix setup
# See the documentation for `Mix` for more info on aliases.
defp aliases do
    [
        setup: ["deps.get", "ecto.setup", "cmd npm install --prefix assets"],
        "ecto.setup": ["ecto.create", "ecto.create -r Backpackingmap.OsmRepo", "ecto.migrate", "ecto.migrate -r Backpackingmap.OsmRepo", "run priv/repo/seeds.exs"],
        "ecto.reset": ["ecto.drop", "ecto.drop -r Backpackingmap.OsmRepo", "ecto.setup", "ecto.setup -r Backpackingmap.OsmRepo"],
        test: ["ecto.create --quiet", "ecto.create --quiet -r Backpackingmap.OsmRepo", "ecto.migrate --quiet", "ecto migrate --quiet -r Backpackingmap.OsmRepo", "test"]
    ]
end
Enter fullscreen mode Exit fullscreen mode

Except the new commands didn't run. It turns out mix deduplicates commands, so we need to change our code to

  defp aliases do
    [
      setup: [
        "deps.get",
        "ecto.setup",
        fn _ -> Mix.Task.reenable("ecto.setup") end,
        "ecto.setup -r Backpackingmap.OsmRepo",
        "cmd npm install --prefix assets"
      ],
      "ecto.setup": [
        "ecto.create",
        fn _ -> Mix.Task.reenable("ecto.create") end,
        "ecto.create -r Backpackingmap.OsmRepo",
        "ecto.migrate",
        fn _ -> Mix.Task.reenable("ecto.migrate") end,
        "ecto.migrate -r Backpackingmap.OsmRepo",
        "run priv/repo/seeds.exs"
      ],
      "ecto.reset": [
        "ecto.drop",
        fn _ -> Mix.Task.reenable("ecto.drop") end,
        "ecto.drop -r Backpackingmap.OsmRepo",
        "ecto.setup",
        fn _ -> Mix.Task.reenable("ecto.setup") end,
        "ecto.setup -r Backpackingmap.OsmRepo"
      ],
      test: [
        "ecto.create --quiet",
        fn _ -> Mix.Task.reenable("ecto.create") end,
        "ecto.create --quiet -r Backpackingmap.OsmRepo",
        "ecto.migrate --quiet",
        fn _ -> Mix.Task.reenable("ecto.migrate") end,
        "ecto.migrate --quiet -r Backpackingmap.OsmRepo",
        "test"
      ]

Enter fullscreen mode Exit fullscreen mode

Top comments (0)