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
Odpowiedz
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
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
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ą (=> #
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
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ć.
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
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ą! –
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
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
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
Jest to jednorazowa, czy chcesz go wielokrotnie pracować na przykład w migracji? –