_toni

_toni

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!

Showing Posts 1 to 10

polypush135

polypush135

/some_release/bin/prod eval "MyApp.Seeder.start_items" :man_shrugging: assuming you are using releases

_toni

_toni OP

Oh, so you suggest to have the Seeder module out of rel/overlays/seeds.exs and instead make it into a module inside /lib/appname/seeder.ex, that sounds like a different approach but a good idea nevertheless :slightly_smiling_face:

polypush135

polypush135

Much like the example in the docs for releases and migrations, I would just follow that pattern.

I mean it could even just go in the Appname.Release module

And just for the record I’m talking about Invoking priv/repo/seeds.exs from that location. Not defining the seeds.exs in there

_toni

_toni OP

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 :slight_smile: 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
polypush135

polypush135

Good question, I’ve never tried to load a exs from inside elixir before. I"m sure it’s simple to do.

dbell

dbell

Code.eval_file/1 will execute an EXS file. That is how I am running migrations via a mix release.

mudasobwa

mudasobwa

Creator of Cure

What’s wrong with Ecto.Migrator.up/4?

polypush135

polypush135

Its for running the seeds.exs
Edit: oh yeah for the migration. Meh to each their own.

mudasobwa

mudasobwa

Creator of Cure

To seed one might pack seeds into a migration and run a migration. There is no mix by default on target release. Of course, another way [not recommended] would be to include mix app in the release.

webuhu

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]

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews