如何在Ecto迁移中运行更新? [英] How to run updating in migration for Ecto?
问题描述
我使用凤凰和
I use Phoenix and Ecto in one of my project.
我想在一个表中添加一列,我希望它是一个 NOT NULL 列.但是我已经有了一些现有的数据,因此我决定添加该列,将所有行更新为某个值,然后将该列修改为 NOT NULL .
I want to add a column to one table, and I expect it to be a NOT NULL column. But I already have some existed data, so I decide to add the column, update all rows to some value and modify the column to NOT NULL.
我尝试了以下两个代码:
I tried these two code:
# 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
他们两个都无法正常工作,并且出现如下错误:
Both of them didn't work and I got error like:
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.
I'm not sure if it's related to the Ecto version but my Ecto version is 2.0.0-rc.0.
有什么办法可以做到这一点?还是我的示例代码有问题?
Is there any way to achieve this? Or is there something wrong in my example code?
推荐答案
Solution #2 is the correct approach, but you need to add a call to Ecto.Migration.flush/0
after the first alter
block to make sure all the changes are executed on the database instantly instead of being queued up to be executed later, which is the default.
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
这篇关于如何在Ecto迁移中运行更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!