2016-04-19 5 views
6

Ich benutze Phoenix und Ecto in einem meiner Projekt.Wie wird die Aktualisierung in der Migration für Ecto ausgeführt?

Ich möchte eine Spalte zu einer Tabelle hinzufügen, und ich erwarte, dass es eine NOT NULL Spalte ist. Aber ich habe bereits einige existierende Daten, also beschließe ich, die Spalte hinzuzufügen, alle Zeilen auf einen Wert zu aktualisieren und die Spalte auf NOT NULL zu ändern.

Ich habe versucht, diese beiden 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 

Beide nicht und ich mag erhielt Fehler funktionierte:

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 

Ich bin mir nicht sicher, ob es auf die Ecto-Version verwandt ist, aber Meine Ecto Version ist 2.0.0-rc.0.

Gibt es eine Möglichkeit, dies zu erreichen? Oder stimmt etwas in meinem Beispielcode nicht?

+2

Versuchen Sie, 'flush()' nach dem ersten 'alter do end' in Ihrer Lösung # 2 hinzuzufügen. Funktioniert es? – Dogbert

+0

Es funktioniert! Vielen Dank! –

+0

Hm ... Derselbe Code wirft '** (ArgumentError) argument error'. Was kann falsch sein? gist - https://gist.github.com/maslenkov/1ca80db913f92a9334a6545eb89880e –

Antwort

17

Lösung # 2 ist der richtige Ansatz, aber Sie müssen Ecto.Migration.flush/0 nach dem ersten alter-Block einen Anruf hinzufügen, um sicherzustellen, dass alle Änderungen sofort in der Datenbank ausgeführt werden statt in die Warteschlange zu später ausgeführt werden der Standard.

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 
Verwandte Themen