【问题标题】:How to run updating in migration for Ecto?如何在迁移中为 Ecto 运行更新?
【发布时间】:2016-08-11 22:16:24
【问题描述】:

我在我的一个项目中使用了PhoenixEcto

我想在一个表中添加一列,我希望它是一个 NOT NULL 列。但我已经有一些现有数据,所以我决定添加列,将所有行更新为某个值并将列修改为 NOT NULL

我试过这两个代码:

  # solution 1
  def up do
    alter table(:channels) do
      add :type, :integer
      Exchat.Repo.update_all("channels", set: [type: 1])
      modify :type, :integer, null: false
    end
  end

  # solution 2
  def up do
    alter table(:channels) do
      add :type, :integer
    end
    Exchat.Repo.update_all("channels", set: [type: 1])
    alter table(:channels) do
      modify :type, :integer, null: false
    end
  end

他们都没有工作,我得到了这样的错误:

23::40::07.514 [info]  == Running Exchat.Repo.Migrations.AddTypeToChannels.up/0 forward

23::40::07.541 [debug] UPDATE "channels" AS c0 SET "type" = $1 [1] ERROR query=12.0ms
** (Postgrex.Error) ERROR (undefined_column): column "type" of relation "channels" does not exist
    (ecto) lib/ecto/adapters/sql.ex:383: Ecto.Adapters.SQL.execute_and_cache/7

我不确定它是否与 Ecto 版本有关,但我的 Ecto 版本是 2.0.0-rc.0。

有什么方法可以实现吗?还是我的示例代码有问题?

【问题讨论】:

  • 尝试在您的解决方案 #2 中的第一个 alter do end 之后添加 flush()。这行得通吗?
  • 有效!谢谢!
  • 嗯...相同的代码引发** (ArgumentError) argument error。有什么问题?要点 - gist.github.com/maslenkov/1ca80dbc913f92a9334a6545eb89880e
  • 好的。这是 Elixometer 的问题。我想我会在那里发布问题......

标签: elixir phoenix-framework ecto


【解决方案1】:

解决方案 #2 是正确的方法,但您需要在第一个 alter 块之后添加对 Ecto.Migration.flush/0 的调用,以确保所有更改都立即在数据库上执行,而不是排队等待稍后执行,这是默认值。

def up do
  alter table(:channels) do
    add :type, :integer
  end
  flush()
  Exchat.Repo.update_all("channels", set: [type: 1])
  alter table(:channels) do
    modify :type, :integer, null: false
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    相关资源
    最近更新 更多