2012-03-02 10 views
19

Mam model z kolumną typu integer, którą chcę przekonwertować na typ string. Teraz szukam najlepszego sposobu na zmianę typu kolumny bez utraty danych przez. Czy istnieje bezbolesny sposób, aby to osiągnąć?Szyny: zmień typ kolumny, ale zachowaj dane

+1

Jest to jednorazowa, czy chcesz go wielokrotnie pracować na przykład w migracji? –

Odpowiedz

33

Standardowa migracja za pomocą metody change_column spowoduje konwersję liczb całkowitych na ciągi bez utraty danych. rake db: rollback wykona również odwrotną migrację bez błędu, jeśli będzie to wymagane.

Oto migracja testu użyłem, aby potwierdzić to zachowanie:

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

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

Z jakiegoś powodu, który nie działa dla mnie. Używam rails 3.2.13 z mysql 14.14 na Macu, a powyższa migracja zmienia wszystkie moje: wartości całkowite na 0 – gardenofwine

+1

Właśnie przeszedłem test z wersjami, o których wspomniałeś (Rails 3.2.13 i mysql Ver 14.14 Distrib 5.5.27, dla osx10.8 (i386) przy użyciu readline 5.1). Wszystko działało zgodnie z oczekiwaniami. Przed migracją (=> # ) po migracji (=> # ). Co robiłeś inaczej w ogrodzie? – Jon

+0

Mam coś podobnego do @gardenofwine, ale konwertuję kolumnę z 'time' na' datetime'. Jeśli oryginalne dane to "09:30:30", po migracji otrzymuję wszystkie zera. Używam Rails 3.2.12 i tej samej wersji mysql co @ Jon. Każdy pomysł, jak to się może stać. – elhoyos

2

Jeśli jest to jednorazowy można po prostu zmienić typ kolumny w bazie danych (ponieważ brak informacji jest stracone przejście z int do varchar)

dla MySQL, byłoby to zrobić:

ALTER TABLE t1 MODIFY col1 VARCHAR(256) 

Jeśli używasz SQLite, nie będziesz musiał nic robić.

+0

Używam postgresql w bieżącym projekcie i to działało również! Dzięki za odpowiedź ustawiłem następujący post jako zaakceptowaną odpowiedź tylko dlatego, że uważam, że większość użytkowników, którzy mają to pytanie, może potrzebować migracji. – blissini

+0

Cool. Tak, odpowiedź migracyjna jest lepsza. Byłem w pracy, pracując na bazie danych MySql w danym momencie, więc odpowiedź na bazę danych pojawiła się przede mną! –

3

dla PostgreSQL w migracji

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

i do każdego ważnego typu podobnym

1

Jeśli używasz PostgreSQL, nie możesz niejawnie rzucić łańcucha z powrotem na liczbę całkowitą, więc sposób zmiany jest odwracalny:

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

dla PostgreSQL, zmiana tabeli kolumna typu danych integer do string,
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 
Powiązane problemy