如果您需要混合任务访问数据库-您需要手动启动ecto回购。在使用ecto 2时,我们使用了ensure_started
函数。
因此带有ecto 2的自定义CLI任务看起来像
defmodule App.Task do
use Mix.Task
import Mix.Ecto
def run(args) do
repos = parse_repo(args)
Enum.each repos, fn repo ->
ensure_repo(repo, args)
ensure_started(repo, []) # was deleted from ecto 3
ensure_started
已从ecto 3中删除。我尝试了几种方法,但它们对我不起作用。有人知道ecto 3的解决方法吗?
已更新
@starbelly提到ensure_started
已迁移到Mix.EctoSQL
,因此我们需要添加额外的import Mix.EctoSQL
才能使其正常工作
defmodule App.Cli.Task do
import Mix.Ecto
import Mix.EctoSQL
def start_ecto do
repos = parse_repo([])
Enum.each(repos, fn repo ->
ensure_repo(repo, [])
{:ok, _pid, _apps} = ensure_started(repo, [])
end)
end
end
答案 0 :(得分:2)
您要导入和调用的函数已移至ecto_sql。您应该import Mix.EctoSQL
换成ensure_started/2
示例:
defmodule Mix.Tasks.Friends.Hello do
use Mix.Task
import Mix.Ecto
import Mix.EctoSQL
def run(args) do
repos = parse_repo(args)
Enum.each(repos, fn repo ->
ensure_repo(repo, args)
{:ok, _pid, _apps} = ensure_started(repo, [])
Friends.Repo.all(Friends.Person)
end)
end
end
答案 1 :(得分:1)
由于Mix.EctoSQL.ensure_started/2
是私有函数,不打算在Ecto之外使用,因此这些方法在最新版本的ecto_sql(3.1.2)中将不再起作用。
As per Jose,正确的方法是使用
Mix.Task.run("app.start")
因此@starbelly共享的示例将被修改为
defmodule Mix.Tasks.Friends.Hello do
use Mix.Task
def run(args) do
Mix.Task.run("app.start")
repos = parse_repo(args)
Enum.each(repos, fn repo ->
repo.all(Friends.Person)
end)
end
end
此方法的最大缺点是,它将启动整个应用程序,包括您拥有的任何后台进程。因此,您可能需要修改application.ex
文件,以免它们由混合任务启动。
答案 2 :(得分:1)
正如丹尼斯指出的那样,Mix.EctoSQL.ensure_started/2
是自ecto_sql 3.1.2起的私有函数,因此我们不能再使用它。
假设您已定义了OTP应用程序(此混合任务是该应用程序的一部分),您可以做的是
defmodule Mix.Tasks.Friends.Hello do
use Mix.Task
def run(args) do
{:ok, _started} = Application.ensure_all_started(:your_otp_app_name)
repos = parse_repo(args)
Enum.each(repos, fn repo ->
repo.all(Friends.Person)
end)
end
end
本质上启动整个OTP应用程序,以便所有依赖项(包括存储库)也将启动。