How to start an upgrade during migration for Ecto?

I use Phoenix and Ecto in one of my projects.

I want to add a column to a single table, and I expect this to be a NOT NULL column. But I already have some existing data, so I decided to add a column, update all rows to some value and change the column to NOT NULL.

I tried these two codes:

# 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 did not work, and I got an error, for example:

 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 

I'm not sure if this is related to the Ecto version, but my version of Ecto is 2.0.0-rc.0.

Is there any way to achieve this? Or is there something wrong with my code example?

+7
source share
1 answer

Solution # 2 is the right approach, but you need to add a call to Ecto.Migration.flush/0 after the first alter block to make sure that all changes are made to the database instantly, and not queued for execution 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 
+18
source

All Articles