Подтвердить что ты не робот

Rails: изменить тип столбца, но сохранить данные

У меня есть модель с столбцом типа integer, который я хочу преобразовать в тип string. Теперь я ищу лучший способ изменить тип столбца без потери данных. Есть ли безболезненный способ достичь этого?

4b9b3361

Ответ 1

Стандартная миграция с использованием метода 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

Ответ 2

для postgres в миграции

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

и любого допустимого типа, подобного

Ответ 3

Если это одноразовое, вы можете просто изменить тип столбца в базе данных (поскольку никакая информация не теряется, переходя из int в varchar)

Для MySQL это сделало бы это:

ALTER TABLE t1 MODIFY col1 VARCHAR(256)

Если вы используете SQLite, вам ничего не нужно делать.

Ответ 4

Если вы используете Postgres, вы не можете неявным образом отбросить строку до целого числа, поэтому способ сделать обратное можно:

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

Ответ 5

для postgresql, измените тип столбца таблицы integer на 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