如何在自定义混合任务中从 Ecto 获取数据
How to get data from Ecto in a custom mix task
我想在自定义混合任务中通过 Ecto 显示我的数据库中的数据。如何在我的任务中获取 Ecto 存储库(或启动它)?
我试过类似的方法,但没有用:
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 users.list 时给我以下输出:
** (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
有解决这个问题的想法或其他方法吗?
您需要确保 repo 在使用前已启动
MyApp.Repo.start_link
外3.x:
ensure_started
已从 Ecto 中删除。围绕这个话题有很多困惑。有关更多信息,请参见此处 https://github.com/elixir-ecto/ecto/pull/2829#issuecomment-456313417。 José 建议使用 Mix.Task.run "app.start"
或 运行 启动应用程序,使用 MyApp.Repo.start_link(...)
.
外2.x:
这曾经在 2.x 中有效,但显然 Mix.Ecto
未被视为 public API.
的一部分
实际上有一个辅助模块Mix.Ecto
(https://github.com/elixir-ecto/ecto/blob/master/lib/mix/ecto.ex)可以更容易地编写使用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 来指定不同的 repo。
➤ 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
确保回购是 运行ning,这是你所缺少的。
如需指导和启发,您可以在 https://github.com/elixir-ecto/ecto/tree/master/lib/mix/tasks
查看其他 ecto mix 任务的实现方式
我在使用 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
它。
作为 Jason Harrelson
答案的补充:还需要启动 Postgrex
和 Ecto
。
[:postgrex, :ecto]
|> Enum.each(&Application.ensure_all_started/1)
MyApp.Repo.start_link
更新:
另一种方法是使用混合任务启动应用程序:
Mix.Task.run "app.start", []
我想在自定义混合任务中通过 Ecto 显示我的数据库中的数据。如何在我的任务中获取 Ecto 存储库(或启动它)?
我试过类似的方法,但没有用:
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 users.list 时给我以下输出:
** (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
有解决这个问题的想法或其他方法吗?
您需要确保 repo 在使用前已启动
MyApp.Repo.start_link
外3.x:
ensure_started
已从 Ecto 中删除。围绕这个话题有很多困惑。有关更多信息,请参见此处 https://github.com/elixir-ecto/ecto/pull/2829#issuecomment-456313417。 José 建议使用 Mix.Task.run "app.start"
或 运行 启动应用程序,使用 MyApp.Repo.start_link(...)
.
外2.x:
这曾经在 2.x 中有效,但显然 Mix.Ecto
未被视为 public API.
实际上有一个辅助模块Mix.Ecto
(https://github.com/elixir-ecto/ecto/blob/master/lib/mix/ecto.ex)可以更容易地编写使用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 来指定不同的 repo。
➤ 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
确保回购是 运行ning,这是你所缺少的。
如需指导和启发,您可以在 https://github.com/elixir-ecto/ecto/tree/master/lib/mix/tasks
查看其他 ecto mix 任务的实现方式我在使用 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
它。
作为 Jason Harrelson
答案的补充:还需要启动 Postgrex
和 Ecto
。
[:postgrex, :ecto]
|> Enum.each(&Application.ensure_all_started/1)
MyApp.Repo.start_link
更新:
另一种方法是使用混合任务启动应用程序:
Mix.Task.run "app.start", []