Как получить данные от Ecto в пользовательской задаче mix
Я хочу отображать данные из моей БД через Ecto в пользовательской задаче mix. Как я могу получить Ecto repo в своей задаче (или запустить ее)?
Я пробовал что-то вроде этого, но это не сработало:
defmodule Mix.Tasks.Users.List do
use Mix.Task
use Mix.Config
use Ecto.Repo, otp_app: :app
@shortdoc "List active users"
@moduledoc """
List active users
"""
def run(_) do
import Ecto.Query, only: [from: 1]
Mix.shell.info "=== Active users ==="
query = from u in "users"
sync = all(query)
Enum.each(users, fn(s) -> IO.puts(u.name) end)
end
end
это даст мне следующий результат при запуске пользователей mix.список:
** (ArgumentError) repo Mix.Tasks.Users.List is not started, please ensure it is part of your supervision tree
lib/ecto/query/planner.ex:64: Ecto.Query.Planner.query_lookup/5
lib/ecto/query/planner.ex:48: Ecto.Query.Planner.query_with_cache/6
lib/ecto/repo/queryable.ex:119: Ecto.Repo.Queryable.execute/5
любая идея или другой способ решить эту проблему?
4 ответов
на самом деле есть вспомогательный модуль Mix.Ecto
(https://github.com/elixir-ecto/ecto/blob/master/lib/mix/ecto.ex), что облегчает написание задач mix, которые используют ecto:
defmodule Mix.Tasks.Users.List do
use Mix.Task
import Mix.Ecto
def run(args) do
repos = parse_repo(args)
Enum.each repos, fn repo ->
Mix.shell.info "=== Active users ==="
ensure_repo(repo, args)
ensure_started(repo, [])
users = repo.all(Ectotask.User)
Enum.each(users, fn(s) -> IO.puts(s.name) end)
end
end
end
этот помощник дает вам доступ к parse_repo/1
, ensure_repo/2
, ensure_started/1
. parse_repo
позволит вашей задаче хорошо вписаться в другие задачи Ecto mix, например, это позволит вам пройти-r, чтобы указать другое РЕПО.
➤ mix users.list
=== Active users ===
Adam
➤ mix users.list -r Ectotask.Repo22
=== Active users ===
** (Mix) could not load Ectotask.Repo22, error: :nofile. Please pass a repo with the -r option.
ensure_started
убеждается что РЕПО бежит, которое вы были недостающий.
для руководства и вдохновения вы можете посмотреть, как другие задачи Ecto mix реализованы в https://github.com/elixir-ecto/ecto/tree/master/lib/mix/tasks
как дополнение к Jason Harrelson
ответ: это также необходимо, чтобы начать Postgrex
и Ecto
.
[:postgrex, :ecto]
|> Enum.each(&Application.ensure_all_started/1)
MyApp.Repo.start_link
обновление:
другой подход-использовать задачу mix для запуска приложения:
Mix.Task.run "app.start", []
Я также нашел другое решение при работе с Phoenix. Я создал новый файл в priv/repo
С :
defmodule Users.List do
def run() do
Mix.shell.info "=== Active users ==="
users = App.Repo.all(App.User)
Enum.each(users, fn(s) ->
Mix.shell.info("#{s.name}")
end)
end
end
Users.List.run
затем я запускаю его с mix run priv/repo/users.list.exs
из моего корневого каталога проекта.