elixir - 在 Ecto 迁移中从另一个 Repo 迁移数据
问题描述
与这个问题类似:Using a Repo in an Ecto migration,我有一个 Ecto 迁移,我想创建一些新表,但也从不同的存储库迁移一些数据。例如:
defmodule MyApp.Repo.Migrations.CreateFoo do
use Ecto.Migration
import Ecto.Query
def change do
create table(:foo) do
add(:status, :text)
end
flush()
execute &import_from_AnotherApp/0
end
defp import_from_AnotherApp()
foos = from(f in AnotherApp.Foo, where: ...)
|> AnotherApp.Repo.all
Enum.each(foos, fn(foo) ->
# Insert data from AnotherApp into MyApp foo table
end)
end
end
问题是在运行 mix ecto.migrate 时我得到了
** (RuntimeError) could not lookup Ecto repo AnotherApp.Repo because it was not started or it does not exist
我尝试将其添加AnotherApp
为 in 的依赖项MyApp
,mix.exs
但仍然出现相同的错误。
这可以做到吗?
解决方案
当您运行混合任务时,它们会在自己的进程中运行,因此其他应用程序(包括包含该任务的主应用程序)可能不会启动。
有时您必须将这样的行放入您的自定义混合任务中,我怀疑您可以将它们放入您的迁移中:
{:ok, _} = Application.ensure_all_started(:my_app)
{:ok, _} = Application.ensure_all_started(:another_app)
但是,有时确保它们已经启动是不够的:有时您必须明确启动该过程。在您的情况下,您必须启动其他应用程序的Ecto.Repo
. 通常,您通过在应用程序的主管中列出Ecto 存储库来启动application.ex
它们,例如
def start(_type, _args) do
children = [
{MyApp.Repo, []},
{AnotherApp.Repo, []},
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
但是,如果您的应用程序的常规功能不需要启动该其他应用程序,那么您可以通过运行手动启动该过程MyApp.Repo.start_link([])
。-- 你可以把它放到你的迁移中,看看它是否出现:
x = MyApp.Repo.start_link([])
IO.inspect(x)
运气好的话,你会得到一个:ok
和一个进程 id,但如果没有,你应该得到一些有用的调试信息。
希望有帮助。
推荐阅读
- ios - AdMob 横幅会在首次加载时出现在首页指示器下方,并且不时出现
- javascript - 提交不断刷新DOM
- c - sarq 和 shrq 的区别
- sql - 删除 SQL 结果中的 SUM 列
- python - 反向列表和添加问题
- javascript - 我无法在 Vue Web JS 中为侧边栏附加我的外部/自定义 JS
- matlab - 具有两个条件的移动窗口 - Matlab
- python - 根据条件创建一个可以等于许多列之一的新列(熊猫)
- java - com.sun.xml.bind:jaxb-impl:2.2.7-b41 在 Weblogic 12.2.1.3 上不兼容
- android - VerticalScroller 在 Column 小部件中不起作用