问题描述
我想在自定义混合任务中通过Ecto显示来自数据库的数据.如何在任务中获取(或启动)Ecto存储库?
I want to display data from my DB through Ecto in a custom mix task. How can I get the Ecto repo in my task (or start it)?
我尝试了类似的方法,但是没有用:
I tried something like this but it didn't work:
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时,这将给我以下输出:
This will give me the following output when I launch 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
有什么办法解决这个问题吗?
Any idea or other way to solve this problem?
推荐答案
Ecto 3.x:
ensure_started
从Ecto中删除.关于这个话题有很多困惑.在这里看到 https://github.com/elixir-ecto/ecto/拉/2829#issuecomment-456313417 了解更多. José建议使用Mix.Task.run "app.start"
启动应用程序,或使用MyApp.Repo.start_link(...)
运行存储库.
ensure_started
has since been removed from Ecto. There has been a lot of confusion around this topic. See here https://github.com/elixir-ecto/ecto/pull/2829#issuecomment-456313417 for more. José suggests to either start the app using Mix.Task.run "app.start"
or run the repo using MyApp.Repo.start_link(...)
.
Ecto 2.x:
该功能以前在2.x中可用,但显然Mix.Ecto
未被认为是公共API的一部分.
This used to work in 2.x, but apparently Mix.Ecto
was not considered part of the public API.
实际上有一个辅助模块Mix.Ecto
( https://github.com/elixir-ecto/ecto/blob/master/lib/mix/ecto.ex ),这样可以更轻松地编写使用ecto的混合任务:
There is actually a helper module Mix.Ecto
(https://github.com/elixir-ecto/ecto/blob/master/lib/mix/ecto.ex) that makes it easier to write mix tasks that use 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混合任务很好地配合,例如,它将使您通过-r来指定其他回购.
This helper gives you access to parse_repo/1
, ensure_repo/2
, ensure_started/1
. parse_repo
will let your task fit in nicely with other ecto mix tasks, for example it will let you pass -r to specify a different 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
确保您正在缺少的仓库正在运行.
ensure_started
makes sure the repo is running, which you were lacking.
作为指导和灵感,您可以在 https://github.com/elixir-ecto/ecto/tree/master/lib/mix/tasks
For guidance and inspiration, you can look at how other ecto mix tasks are implemented at https://github.com/elixir-ecto/ecto/tree/master/lib/mix/tasks
这篇关于如何在自定义混合任务中从Ecto获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!