Запуск миграций с выпусками Docker Distillery
Я пытаюсь развернуть приложение Phoenix 1.3. Я настроил mix docker
выпустить сборку. Теперь я выясняю, как запустить миграцию.
Я решил пойти с подходом с созданием пользовательской команды выпуска. Я создал такой MigrationTask:
defmodule SfiBackend.ReleaseTasks do
@start_apps [
:crypto,
:ssl,
:postgrex,
:ecto,
:logger
]
def myapp do
Application.ensure_started(:sfi_backend)
Enum.each(@start_apps, fn app -> Application.ensure_started(app) end)
Application.get_application(__MODULE__) |> IO.inspect(label: "My application:")
end
def repos, do: Application.get_env(myapp(), :ecto_repos, []) |> IO.inspect(label: "Repose:")
def seed do
me = myapp()
IO.puts "Loading #{me}.."
# Load the code for myapp, but don't start it
:ok = Application.load(me)
IO.puts "Starting dependencies.."
# Start apps necessary for executing migrations
Enum.each(@start_apps, &Application.ensure_all_started/1)
# Start the Repo(s) for myapp
IO.puts "Starting repos.."
Enum.each(repos(), &(&1.start_link(pool_size: 1)))
# Run migrations
migrate()
# Run seed script
Enum.each(repos(), &run_seeds_for/1)
# Signal shutdown
IO.puts "Success!"
:init.stop()
end
def migrate, do: Enum.each(repos() |> IO.inspect(), &run_migrations_for/1)
def priv_dir(app), do: "#{:code.priv_dir(app)}"
defp run_migrations_for(repo) do
app = Keyword.get(repo.config, :otp_app)
IO.puts "Running migrations for #{app}"
Ecto.Migrator.run(repo, migrations_path(repo), :up, all: true)
end
def run_seeds_for(repo) do
# Run the seed script if it exists
seed_script = seeds_path(repo)
if File.exists?(seed_script) do
IO.puts "Running seed script.."
Code.eval_file(seed_script)
end
end
def migrations_path(repo), do: priv_path_for(repo, "migrations")
def seeds_path(repo), do: priv_path_for(repo, "seeds.exs")
def priv_path_for(repo, filename) do
app = Keyword.get(repo.config, :otp_app)
repo_underscore = repo |> Module.split |> List.last |> Macro.underscore
Path.join([priv_dir(app), repo_underscore, filename])
end
end
Технически он должен работать, потому что я скопировал его из Distillery Repo, но это не так.
Я получаю такую ошибку:
My application:: :sfi_backend
Repose:: [SfiBackend.Repo]
[SfiBackend.Repo]
Running migrations for sfi_backend
init terminating in do_boot ()
{"init terminating in do_boot",{#{'__exception__'=>true,'__struct__'=>'Elixir.ArgumentError',message=><<"argument error">>},[{ets,lookup_element,['Elixir.Ecto.Registry',nil,3],[]},{'Elixir.Ecto.Registry',lookup,1,[{file,"lib/ecto/registry.ex"},{line,18}]},{'Elixir.Ecto.Adapters.SQL',sql_call,6,[{file,"lib/ecto/adapters/sql.ex"},{line,251}]},{'Elixir.Ecto.Adapters.SQL','query!',5,[{file,"lib/ecto/adapters/sql.ex"},{line,198}]},{'Elixir.Ecto.Adapters.Postgres','-execute_ddl/3-fun-0-',4,[{file,"lib/ecto/adapters/postgres.ex"},{line,85}]},{'Elixir.Enum','-reduce/3-lists^foldl/2-0-',3,[{file,"lib/enum.ex"},{line,1755}]},{'Elixir.Ecto.Adapters.Postgres',execute_ddl,3,[{file,"lib/ecto/adapters/postgres.ex"},{line,85}]},{'Elixir.Ecto.Migrator','-migrated_versions/2-fun-0-',2,[{file,"lib/ecto/migrator.ex"},{line,44}]}]}}
Crash dump is being written to: erl_crash.dump...done
1 ответ
Из стека трассировки видно, что он не может найти ваш репозиторий после поиска по имени:
вот lookup
функция из экто 2.2:
def lookup(repo_name) do
pid = GenServer.whereis(repo_name)
:ets.lookup_element(__MODULE__, pid, 3)
end
Это приведет к ошибке аргумента, если pid
является nil
, Похоже, вы начинаете репо в seed
но не в migrate
# Start the Repo(s) for myapp
IO.puts "Starting repos.."
Enum.each(repos(), &(&1.start_link(pool_size: 1)))
Переведите этот код в другую функцию и вызовите его из migrate
чтобы убедиться, что Репо запущены.