2012-09-26 18 views
20

Próbuję wykonać następującą się migrację zmienić kolumny „numer” w stole „tweet” modeluSzyny migracji Błąd w/PostgreSQL podczas pchania do Heroku

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 

Po wykonaniu następujących górę migracja do Heroku ....

heroku rake db:migrate:up VERSION=20120925211232 

otrzymuję następujący błąd

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

wszelkie myśli masz Byłbym bardzo doceniony.

Dziękuję wszystkim.

Odpowiedz

31

Z fine manual:

[ALTER TABLE ... ALTER COLUMN ...]
Opcjonalny USING klauzula określa sposób obliczyć nową wartość kolumny ze starego; jeśli zostanie pominięty, domyślna konwersja jest taka sama, jak przypisanie przeniesione ze starego typu danych do nowego. Należy podać klauzulę USING, jeśli nie ma żadnych niejawnych lub przypisania od starego do nowego typu.

Nie ma niejawna konwersja z varchar do int w PostgreSQL tak zarzuca ona column "number" cannot be cast to type integer i ALTER TABLE się nie powiedzie. Musisz powiedzieć PostgreSQL, jak konwertować stare łańcuchy na liczby, aby pasowały do ​​nowego typu kolumny, a to oznacza, że ​​musisz wprowadzić klauzulę USING do tabeli ALTER. Ja nie znam żadnego sposobu, aby zrobić dla Rails można ale trzeba to zrobić ręcznie łatwo wystarczy:

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

Będziemy chcieli zwrócić uwagę na wartości, które nie mogą być oddane do liczb całkowitych, PostgreSQL poinformuje Cię, jeśli wystąpią problemy i będziesz musiał je naprawić, zanim migracja się powiedzie.

Twoja obecna migracja w dół powinna być w porządku, konwersja integer na varchar powinna być obsługiwana automatycznie.

+0

bardzo ciekawe - dzięki! – dougiebuckets

+0

Aby uzyskać bardziej zwięzły i idiomatyczny sposób na zrobienie tego, sprawdź poniżej odpowiedź Rileya! – danmaz74

+0

@ danmaz74: Czy wiesz, czy to było dostępne w 2012 roku, czy też coś przegapiłem? –

46

samo jak powyżej, ale trochę bardziej zwięzły:

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

Wygląda na to, że AR powinien sobie z tym poradzić – Rob

+1

Użyj tego do migracji w takim przypadku: 'reversible do | dir | dir.up do change_column: yourtable,: column_to_change, 'integer UŻYWAJĄC CAST ("column_to_change" AS integer)' koniec koniec reż.down do change_column: yourtable,: column_to_change, 'znak różny UŻYCIE CAST ("column_to_change" AS różni się)' koniec koniec' – febeling

Powiązane problemy