2012-09-26 42 views
20

我试图执行跟进迁移更改“推”模式的表Rails的迁移错误瓦特/ Postgres的推到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 

列“数字”在执行时将跟进迁移到Heroku的....

heroku rake db:migrate:up VERSION=20120925211232 

我收到以下错误

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

有什么想法你有将非常感激。

谢谢大家。

回答

31

fine manual

[ALTER TABLE ... ALTER COLUMN ...]
可选USING子句指定如何计算从旧的新的列值;如果省略,则默认转换与从旧数据类型到新转换的赋值相同。如果不存在从旧类型到新类型的隐式或赋值转换,则必须提供USING子句。

有来自varchar在PostgreSQL里没有隐式转换为int所以抱怨column "number" cannot be cast to type integer和ALTER TABLE失败。您需要告诉PostgreSQL如何将旧字符串转换为数字以匹配新列类型,这意味着您需要在ALTER TABLE中获得USING子句。我不知道有什么办法让Rails的为你做的,但你可以用手轻易够做到这一点:

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

你要注意的是不能转换为整数值, PostgreSQL会让你知道是否有问题,你必须在迁移成功之前解决它们。

您现有的向下迁移应该没问题,应将integer转换为varchar应自动处理。

+0

非常有趣 - 谢谢! – dougiebuckets

+0

要了解更简洁和习惯的方法,请查看下面的riley答案! – danmaz74

+0

@ danmaz74:你知道这是在2012年推出还是我错过了什么? –

46

同上,但一点点更简洁:

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

感觉像AR应该处理这个真的 – Rob

+1

在这种情况下使用这个可逆迁移: 'reversible do | dir | dir.up do change_column:yourtable,:column_to_change,'integer USING CAST(“column_to_change”AS integer)' end dir。向下做 change_column:yourtable,:column_to_change,'字符变化USING CAST(“column_to_change”AS字符变化)' end end' – febeling