Ecto 3-在自定义CLI任务中启动回购

时间:2018-12-12 11:42:24

标签: elixir ecto

如果您需要混合任务访问数据库-您需要手动启动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

3 个答案:

答案 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应用程序,以便所有依赖项(包括存储库)也将启动。