7

Railsでの移行。文字列型の列をbigintに変更するにはどうすればよいですか?

私は持っています:

t.change :ip_number_from, :integer, :limit => 8

私は得る:

PG::Error: ERROR:  column "ip_number_from" cannot be cast to type bigint

私も2つの選択肢で試しました:

change_column :ip_to_countries, :ip_number_from, :integer, :limit => 8
change_column :ip_to_countries, :ip_number_from, :bigint

それでも同じエラー。

4

4 に答える 4

14

Postgresは、変換方法がわからない既存のデータがその列にあることを通知しているため、既存の値をキャストする方法を指定するために、列にUSING句を提供するALTERステートメントが必要です。

残念ながら、これを実現するには、データベース固有のコードをドロップダウンするか、ここで提案されているソリューションと同様のコードを使用する必要があります。

http://webjazz.blogspot.co.uk/2010/03/how-to-alter-columns-in-postgresql.html

編集:移行時にSQLで直接行う方法は次のとおりです。

execute <<-SQL
  ALTER TABLE ip_to_countries
  ALTER COLUMN ip_number_from TYPE bigint USING ip_number_from::bigint
SQL
于 2012-04-30T08:28:41.683 に答える
3

ip_number_from列には何がありますか?

いずれにせよ、私はおそらく:

  • タイプbigintの新しい列を作成します。
  • Railsコンソールまたはrakeタスクを使用して、ip_number_fromからnew_columnにデータを手動でコピーします。
  • 元のip_number_from列を削除します
  • new_columnの名前をip_number_fromに変更します

または、mjtkoが提案したように、SQLにドロップダウンすることもできますが、それがもっと簡単になるかどうかはわかりません。

アップデート

ユールが提案していることを調べました。データのキャスト/コピーが成功したかどうかを実際に確認することはできないため、1回の移行でこれらすべてを実行するのは少し危険だと思います。1回の移行でそれを実行したい場合、あなたの場合は次のようになります。

def up
  add_column :table, :new_column, :bigint
  Model.reset_column_information
  Model.all.each do |m|
    m.update_attribute :new_column, Model.bigint_from_ip_number_from(m)
  end
  drop_column :table, :ip_number_from
  rename_column :table, :new_column, :ip_number_from
end

次に、対応するダウンマイグレーションを追加する必要があります。

これはいつでも複数の移行に分割して、進行状況/成功を確認できます。

于 2012-04-30T08:30:33.733 に答える
0

最近読んだのですが、どこにあるかは覚えていませんが、「string」列を「int」列にキャストすることはできませんが、逆のことはできます。「int」から「string」へのキャストは、元に戻せない移行操作です。

それを読んだドキュメントを検索し、見つかったら投稿を編集します。

可能であれば、最も簡単な方法は、JureTriglavが提案していることです。(彼は私の前に彼の答えを投稿しましたが、私は同じことを提案していました;))。

[編集]私はそれを読んだところに戻って見つけました:不可逆的な移行tuto

于 2012-04-30T08:32:23.707 に答える
0

change_column :table_name, :column_name, 'TYPE bigint USING CAST(column_name AS TYPE bigint)'

于 2021-01-18T05:49:33.193 に答える