21

「ツイート」モデルのテーブルの「番号」列を変更するために、次のアップマイグレーションを実行しようとしています。

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古いタイプから新しいタイプへの暗黙的または割り当てキャストがない場合は、句を指定する必要があります。

varcharPostgreSQLにはからへの暗黙の変換がないintため、それが文句を言いcolumn "number" cannot be cast to type integer、ALTERTABLEは失敗します。新しい列タイプに一致するように古い文字列を数値に変換する方法をPostgreSQLに指示する必要があります。つまり、ALTERTABLEにUSING句を取得する必要があります。Railsにそれを行わせる方法はわかりませんが、手作業で簡単に行うことができます。

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

整数にキャストできない値に注意する必要があります。PostgreSQLは問題があるかどうかを通知し、移行が成功する前にそれらを修正する必要があります。

既存のダウンマイグレーションは問題なく、への変換は自動的に処理integerされるvarcharはずです。

于 2012-09-26T16:05:56.737 に答える