2012-09-26 13 views
20

Ich versuche, die Follow-up-Migration auszuführen, um die Spalte „Nummer“ in dem „tweet“ Tisch ModellRails Migration Fehler w/Postgres, wenn zu Heroku drängt

class ChangeDataTypeForTweetsNumber < ActiveRecord::Migration 
    def up 
    change_column :tweets do |t| 
     t.change :number, :integer 
    end 
    end 

    def down 
    change_table :tweets do |t| 
     t.change :number, :string 
    end 
    end 
end 

ändert die folgenden Beim Durchführen up Migration zu Heroku ....

heroku rake db:migrate:up VERSION=20120925211232 

bekomme ich folgende Fehler

PG::Error: ERROR: column "number" cannot be cast to type integer 
: ALTER TABLE "tweets" ALTER COLUMN "number" TYPE integer 

Irgendwelche Gedanken, die Sie haben würde sehr geschätzt werden.

Danke an alle.

Antwort

31

Vom fine manual:

[ALTER TABLE ... ALTER COLUMN ...]
Die optionale USING Klausel gibt an, wie die neue Spalte Wert aus dem alten zu berechnen; Wenn sie weggelassen wird, entspricht die Standardkonvertierung einer Zuweisung, die vom alten Datentyp in den neuen Datentyp umgewandelt wurde. Eine USING-Klausel muss angegeben werden, wenn keine implizite oder Zuweisungsumsetzung vom alten zum neuen Typ erfolgt.

Es gibt keine implizite Konvertierung von varchar zu int in PostgreSQL so, dass column "number" cannot be cast to type integer beschwert und die ALTEN TABLE schlägt fehl. Sie müssen PostgreSQL mitteilen, wie die alten Strings in Zahlen konvertiert werden, damit sie dem neuen Spaltentyp entsprechen. Das bedeutet, dass Sie eine USING-Klausel in Ihre ALTER TABLE aufnehmen müssen. Ich weiß nicht von irgendeiner Weise Rails machen Sie das für Sie, aber Sie können es tun, von Hand leicht genug:

def up 
    connection.execute(%q{ 
    alter table tweets 
    alter column number 
    type integer using cast(number as integer) 
    }) 
end 

Sie werden für Werte aufpassen möchten, die nicht auf ganze Zahlen gegossen werden kann, PostgreSQL wird Sie wissen lassen, wenn es Probleme gibt, und Sie müssen sie beheben, bevor die Migration erfolgreich sein wird.

Ihre bestehende Abwärtsmigration sollte in Ordnung sein, die Konvertierung integer in varchar sollte automatisch durchgeführt werden.

+0

sehr interessant - danke! – dougiebuckets

+0

Für eine prägnantere und idiomatische Art und Weise, es zu tun, sehen Sie sich Riley's Antwort unten an! – danmaz74

+0

@ danmaz74: Weißt du, ob das 2012 verfügbar war oder habe ich etwas verpasst? –

46

Wie oben, aber ein wenig mehr prägnant:

change_column :yourtable, :column_to_change, 'integer USING CAST("column_to_change" AS integer)' 
+0

Fühlt sich wie AR sollte dies wirklich handhaben – Rob

+1

Verwenden Sie dies für eine reversible Migration in diesem Fall: 'reversible do | dir | dir.up do change_column: yuertable,: spalte_zu_change, 'integer VERWENDUNG VON CAST ("column_to_change" AS ganze Zahl)' Ende dir.down do change_column: yuertable,: column_to_change, 'Zeichen variiert mit USING CAST ("column_to_change" AS Zeichen variiert)' Ende Ende ' – febeling