【问题标题】:Old ecto migration failing to run because I added a new field to model schema旧的 ecto 迁移无法运行,因为我在模型模式中添加了一个新字段
【发布时间】:2018-03-14 04:44:01
【问题描述】:

我有一个旧迁移,它会在角色数组字段中更新用户的角色。

此迁移不再运行,因为今天我在架构中添加了一个名为 is_bot 的字段。

这是我的迁移的样子:

def up do
  query =
    from(
      u in "users",
      select: %{id: u.id, email: u.email, onboarded: u.onboarded, roles: u.roles}
    )

  Repo.transaction(
    fn ->
      query
      |> Repo.stream()
      |> Stream.each(fn user ->
        cond do
          user.onboarded && user.roles != nil && length(user.roles) > 1 ->
            roles = ["test"]

            user
            |> Repo.update_all(set: [roles: roles])

          true ->
            IO.puts("User #{user.email} has no roles. Onboarded: #{user.onboarded}")
        end
      end)
      |> Stream.run()
    end,
    timeout: :infinity
  )
end

还有我的架构:

schema "users" do
  field(:email, :string)
  field(:roles, {:array, :string})
  field(:onboarded, :boolean, default: false)
  field(:is_bot, :boolean, default: false)
end

我想通过使用u in "users",我会避免在我的模型中遍历我的架构,但无论如何它似乎都在使用它。

错误:

** (Postgrex.Error) ERROR 42703 (undefined_column): column u0.is_bot does not exist
(db_connection) lib/db_connection.ex:1406: DBConnection.prepare_declare/4
(elixir) lib/stream.ex:1270: anonymous fn/5 in Stream.resource/3
(elixir) lib/stream.ex:1433: Enumerable.Stream.do_each/4
(elixir) lib/stream.ex:806: Stream.do_transform/8
(elixir) lib/stream.ex:1433: Enumerable.Stream.do_each/4
(elixir) lib/stream.ex:591: Stream.run/1
(ecto) lib/ecto/adapters/sql.ex:576: anonymous fn/3 in Ecto.Adapters.SQL.do_transaction/3
(db_connection) lib/db_connection.ex:1275: DBConnection.transaction_run/4

如何运行此迁移?

【问题讨论】:

  • 你检查过 is_bot 是否是数据库中的一个字段吗?您是如何“将今天添加到架构中的?
  • 如果您在架构中手动添加该字段并且数据库不知道该字段它将失败
  • @SimonFranzen 我通过更新的迁移文件添加了 is_bot 字段。问题仍然存在。

标签: postgresql migration elixir ecto


【解决方案1】:

您正在滥用迁移来运行种子。您可能应该做的是将种子代码移至seeds/update_roles.exs 的某个位置,并使用此别名设置ecto(在mix.exs 文件中):

defp aliases do
  [
    "ecto.setup": ["ecto.create", "ecto.migrate", "run seeds/update_roles.exs"],
    ...

这样,数据库将首先完全设置为现代版本,然后然后植入数据。当前代码尝试使用包含 is_bot 字段的架构在尚未包含它的数据库上运行种子。

【讨论】:

  • 这就是要走的路!
猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 2019-02-28
  • 2015-08-03
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
相关资源
最近更新 更多