How can I run seeds.exs before starting application?

I’ve just recently added a new worker for my supervision tree and this worker on init does a DB lookup to load up some data. However that data does not exist until seeds.exs is ran. Previously I had no such dependency and my mix aliases worked fine.

    ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test": ["ecto.drop --quiet", "ecto.create --quiet", "ecto.migrate", "run priv/repo/seeds.exs", "test"]]
  end```

Is there some way I can get around this issue?
2 Likes

If I understand you correctly, your problem is that when you try to run any mix task, you get an error on your worker because your db is not seeded, and you can’t run your seeds for the same reason. Am I right?

Can you give more details about it?

Yes that’s correct. The worker needs the db to be seeded to start up correctly but it seems doing ‘run …/seeds.exs’ causes the application to start up which means the worker.

1 Like

Did you try —no-start?

https://hexdocs.pm/mix/Mix.Tasks.Run.html

1 Like

Tried and it fails because it doesn’t start up the Ecto processes. I’m starting to think I might need to make the seed dependent process transient or some way not start up until needed.

1 Like

ok so… I think you are doing something wrong. First of all, you are making your application dependent on external input source - the database. Which generally is bad but you make it worse by making application startup dependent on the external input - database state.

Have a look at what Phoenix is doing on it’s own: it starts the application no matter if the database connection is established properly or not. Yes, it will crash. But it will also retry reconnect every few seconds and if it does connect - it’ll start working as expected.

This is the pattern you can employ. If can’t load the state, fail. Retry after a few seconds.

2 Likes

Can you start :ecto in your seed script directly?

https://hexdocs.pm/elixir/Application.html#ensure_all_started/2

1 Like

mix run starts the whole app before running your file. You should create a mix task which just starts the :ecto and your Repo using start_link and then runs your seed file.

1 Like

I’m not familiar with creating tasks. How would I go about starting up ecto? Would I use Agent.start_link?

1 Like

I added handling in the genserver for the DB not being set up at start up of the application. This solves my seeding problem. I’ll still look into seeding without starting up my application. Thanks.

1 Like

You can check how they do on ecto tasks! :slight_smile:

Oh yeah, of course! Thanks. I’ll take a look.

Note: In Ecto 2.x you shouldn’t be using import Mix.Ecto in your own code since it is considered a private api. Although it looks like this is changed in Ecto 3.0

2 Likes