2016-04-19 8 views
6

私のプロジェクトではPhoenixEctoを使用しています。Ectoの移行での更新の実行方法

1つのテーブルに列を追加したいと思いますが、それはNOT NULLの列になると思います。しかし、私はすでにいくつかの既存のデータを持っているので、私は列を追加し、すべての行をいくつかの値に更新し、列をNOT NULLに変更することに決めました。

が、私はこれらの2つのコードを試みた:

# 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バージョンは2.0.0-rc.0です。

これを達成する方法はありますか?あるいは、私のサンプルコードに何か間違っていますか?

+2

解決策#2の最初の 'alter do end'の後に' flush() 'を追加してみてください。それは動作しますか? – Dogbert

+0

それは動作します!ありがとうございました! –

+0

Hm ...同じコードで '**(ArgumentError)argument error'が発生します。何が間違っていますか?要点 - https://gist.github.com/maslenkov/1ca80dbc913f92a9334a6545eb89880e –

答えて

17

解決策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 
関連する問題