_toni
Mix Release. Run seeds.exs file via release binary
Hello,
When one is within the Mix context it’s possible to run
$ mix run priv/repo/seeds.exs
Which will evaluate code like the following into the DB:
#/priv/repo/seeds.exs ---> copied to _build/rel/appname/prod/seeds.exs once release is built
defmodule Seeder do
def start_items do
%Item{}
|> Item.changeset(%{name: Faker.Commerce.product_name()})
|> Repo.insert!()
do
end
Seeder.start_items()
I would like to also run the same script in production from a mix release binary à la
./bin/appname eval "Appname.Release.migrate"
What is the recommended way? I already copied the seeds.exs to overlays so they are located in here
_build/rel/appname/prod/seeds.exs
Thank you!
Marked As Solved
dbell
Code.eval_file/1 will execute an EXS file. That is how I am running migrations via a mix release.
Also Liked
webuhu
I currently use the following in one of my projects:
defmodule MyApp.Release.Seeder do
@moduledoc """
Release tasks for seeds.
"""
require Logger
@app :my_app
@doc """
Seed seeds file for repo.
"""
@spec seed(Ecto.Repo.t(), String.t()) :: :ok | {:error, any()}
def seed(repo, filename) do
load_app()
case Ecto.Migrator.with_repo(repo, &eval_seed(&1, filename)) do
{:ok, {:ok, _fun_return}, _apps} ->
:ok
{:ok, {:error, reason}, _apps} ->
Logger.error(reason)
{:error, reason}
{:error, term} ->
IO.warn(term, [])
{:error, term}
end
end
@spec eval_seed(Ecto.Repo.t(), String.t()) :: any()
defp eval_seed(repo, filename) do
seeds_file = get_path(repo, "seeds", filename)
if File.regular?(seeds_file) do
{:ok, Code.eval_file(seeds_file)}
else
{:error, "Seeds file not found."}
end
end
@spec get_path(Ecto.Repo.t(), String.t(), String.t()) :: String.t()
defp get_path(repo, directory, filename) do
priv_dir = "#{:code.priv_dir(@app)}"
repo_underscore =
repo
|> Module.split()
|> List.last()
|> Macro.underscore()
Path.join([priv_dir, repo_underscore, directory, filename])
end
@spec load_app() :: :ok | {:error, term()}
defp load_app(), do: Application.load(@app)
end
And then for the release:
bin/my_app eval 'MyApp.Release.Seeder.seed(Elixir.MyApp.Repo, "seed.exs")
PS: You probably need to add to your config.exs
config :my_app, MyApp.Repo,
start_apps_before_migration: [:logger]
polypush135
/some_release/bin/prod eval "MyApp.Seeder.start_items"
assuming you are using releases
_toni
Following Deploying with Releases — Phoenix v1.8.8 for migrations I got stuck when it comes to the seeds due to the fact that they by consensus live in a script .exs which I assumed requires the mix tool to the mix runex.
Ah cool. Even better
Can you briefly annotate how that invoking would look like, I did find its full path via priv_dir(:appname) function but didn’t figure out how to run the script itself.
defmodule Appname.Release do
def run_seeds do
# Load seeds.exs script here
end
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









