2012-03-02 3 views
19

に変換するintegerタイプの列のモデルがあります。今私はデータを失うことなく、列の種類を変更する最良の方法を探しています。これを達成するための無痛な方法はありますか?Rails:列タイプを変更しますが、データを保持

+1

これは一回限りですか、あなたはそれが移行して、例えば、繰り返し仕事をしたいですか? –

答えて

33

change_columnメソッドを使用した標準的な移行では、データを失うことなく整数を文字列に変換します。 rake db:rollbackは、必要に応じてエラーなしで逆方向移行も行います。ここで

は、私は、この動作を確認するために使用するテスト移行である:

class ChangeAgeToString < ActiveRecord::Migration 
    def self.up 
    change_column :users, :age, :string 
    end 

    def self.down 
    change_column :users, :age, :integer 
    end 
end 
+0

何らかの理由でそれは私にとってはうまくいかない。私はMac上でmysql 14.14を使ってrails 3.2.13を使用しています。上記のマイグレーションはすべて私の整数値を0に変更します – gardenofwine

+1

私はあなたが言及したバージョン(Rails 3.2.13およびmysql Ver 14.14 readline 5.1を使用したosx10.8(i386)の5.5.27の配布。すべてが期待どおりに機能しました。移行前(=>#<ユーザーID:1、年齢:12、created_at: "2013-04-16 13:52:04"、updated_at: "2013-04-16 13:52:04">) =>#<ユーザーID:1、年齢: "12"、created_at: "2013-04-16 13:52:04"、updated_at: "2013-04-16 13:52:04">)。あなたはガーデモワインをどうやってやったのですか? – Jon

+0

@ gardenofwineと似たようなことが起こっていますが、列を 'time'から' datetime'に変換しています。元のデータが "09:30:30"の場合、移行後にはすべてゼロになります。私はRails 3.2.12と@Jonと同じバージョンのmysqlを使っています。どのようにこれが起こることができるか考えてください。 – elhoyos

2

それは一回限りだ場合はただ、これはそれを行うだろう、MySQLの場合(何も情報がvarchar型にint型から移動失われないため)、データベースに

を列の型を変更することができます。

ALTER TABLE t1 MODIFY col1 VARCHAR(256) 

SQLiteを使用している場合は、何もする必要はありません。

+0

私は現在のプロジェクトでpostgresqlを使用しています。 答えをいただきありがとうございます。この質問があるほとんどのユーザーが移行を必要とする可能性があるため、次の投稿を承認済みの回答として設定します。 – blissini

+0

Cool。ええ、移行の答えが良いです。私は実際に働いていました。当時のMySql DBで作業していたので、データベースの回答が私に最初に現れました! –

3
postgresのため

移行中

change_column :table_name, :field,'boolean USING (CASE field WHEN \'your any string as true\' THEN \'t\'::boolean ELSE \'f\'::boolean END)' 

1

同様の任意の有効なタイプにあなたがPostgresのを使用している場合は、暗黙的に文字列を整数にキャストすることはできないので、変更を元に戻す方法は次のとおりです。

stringのpostgresql、チェンジ・テーブルのカラムのデータ型 integerため
class ChangeAgeToString < ActiveRecord::Migration 
    def self.up 
    change_column :users, :age, :string 
    end 

    def self.down 
    add_column :age_integer 
    User.connection.execute('UPDATE users SET age_integer = cast(age as int)') 
    remove_column :users, :age 
    rename_column :users, :age_integer, :age 
    end 
end 
0


rails migration like this with up and down actions

class ChangeAgeToString < ActiveRecord::Migration 
    def self.up 
    change_column :users, :age, 'varchar USING CAST(age AS varchar)', null: false 
    end 

    def self.down 
    change_column :users, :age, 'integer USING CAST(age AS integer)', null: false, default: 0 
    end 
end 
関連する問題