2012-09-26 11 views
20

Estoy tratando de realizar el seguimiento de la migración de cambiar la columna "número" en la tabla del modelo de "Tweet"rieles Migración de error w/Postgres al empujar a 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 

Al realizar la siguiente hasta la migración a heroku ....

heroku rake db:migrate:up VERSION=20120925211232 

me sale el siguiente error

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

Cualquier pensamiento que tiene Sería muy apreciado.

Gracias a todos.

Respuesta

31

Desde el fine manual:

[... ALTER TABLE ALTER COLUMN ...]
La cláusula opcional USING especifica cómo calcular el nuevo valor de la columna de la edad; si se omite, la conversión predeterminada es la misma que la conversión de asignación del tipo de datos antiguo a nuevo. Se debe proporcionar una cláusula USING si no hay un reparto implícito o de asignación del tipo antiguo al nuevo.

No hay conversión implícita de varchar a int en PostgreSQL por lo que se queja de que column "number" cannot be cast to type integer y falla la ALTER TABLE. Necesita decirle a PostgreSQL cómo convertir las cadenas antiguas en números para que coincidan con el nuevo tipo de columna, lo que significa que debe obtener una cláusula USING en su ALTER TABLE. No sé de ninguna manera de hacer rieles hacer eso por usted, pero usted puede hacerlo a mano con bastante facilidad:

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

Usted querrá tener cuidado con los valores que no se puede convertir a números enteros, PostgreSQL te avisará si hay problemas y tendrás que solucionarlos antes de que la migración tenga éxito.

Su migración descendente existente debería estar bien, la conversión de integer a varchar se debe manejar automáticamente.

+0

muy interesante - gracias! – dougiebuckets

+0

Para una forma más concisa e idiomática de hacerlo, ¡revisa la respuesta de riley a continuación! – danmaz74

+0

@ danmaz74: ¿Sabes si estuvo disponible en 2012 o me perdí algo? –

46

Igual que el anterior pero un poco más concisa:

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

Se siente como AR debe manejar esto realmente – Rob

+1

Use esto para una migración reversible en ese caso: 'reversible do | dir | dir.up do change_column: yourtable,: column_to_change, 'entero USING CAST ("column_to_change" AS integer)' end dir.abajo hacer change_column: yourtable,: column_to_change, 'carácter que varía USING CAST ("column_to_change" COMO el carácter que varía)' end end' – febeling

Cuestiones relacionadas