21

我正在尝试执行后续迁移以更改“tweet”模型表中的“number”列

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

您的任何想法将不胜感激。

感谢大家。

4

2 回答 2

46

与上面相同,但更简洁一点:

change_column :yourtable, :column_to_change, 'integer USING CAST("column_to_change" AS integer)'
于 2013-10-16T07:51:09.653 回答
32

来自精美手册

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

PostgreSQL中没有从varchartoint的隐式转换,因此它抱怨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 会通知您,您必须在迁移成功之前修复它们。

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

于 2012-09-26T16:05:56.737 回答