我有一个 Ecto 迁移,我想修改一些列,但也迁移一些数据。例如:
import Ecto.Query
defmodule MyApp.Repo.Migrations.AddStatus do
alter table(:foo) do
add(:status, :text)
end
foos = from(f in MyApp.Foo, where: ...)
|> MyApp.Repo.all
Enum.each(foos, fn(foo) ->
# There's then some complex logic here to work
# out how to set the status based on other attributes of `foo`
end)
end
现在,这里的问题是通过调用
MyApp.Repo.all
迁移本质上使用单独的数据库连接到 alter table...
使用的语句( 编辑 :此假设是错误的,请参阅已接受的答案)。因此,没有 status
列所以整个迁移爆炸了!请注意,我们使用的是 postgres
数据库,因此 DDL 语句是事务性的。我可以将其作为两个单独的迁移或
mix
来完成。任务来设置数据,只为架构更改留下迁移,但为了确保数据一致性,不希望这样做。关于如何为
MyApp.Repo
使用相同的数据库连接的任何想法以这种方式查询?编辑 :请注意,我正在处理一小组数据,在我的用例中,停机时间是可以接受的。如果情况并非如此,请参阅下面 José 的回复以获取一些好的建议。
最佳答案
一般来说,同时进行数据迁移和更改 DDL 是一种不好的做法。如果这是一个实时系统并且迁移需要很长时间,您可能会在很长一段时间内产生大量争用。
如果您的应用程序仍在处理请求,则可以在处理数据时添加新条目,而不会处理这些条目!
有不同的方法来解决这个问题,具体取决于用例,但它们通常需要循序渐进的方法。例如,如果您要添加一个新列:
关于elixir - 在 Ecto 迁移中使用 Repo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48381568/