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

Как переименовать столбец и изменить его тип путем миграции одновременно

В моей таблице general_exams у меня есть столбец с именем semester, введите string. Теперь я хочу изменить его имя на semester_id, введите integer. Я прочитал о миграции и имеет доступные преобразования:

  • rename_column (table_name, column_name, new_column_name): переименовывает столбец, но сохраняет тип и содержимое.
  • change_column (table_name, column_name, type, options): изменяет столбец на другой тип, используя те же параметры, что и add_column.

Итак, я создаю свой файл миграции следующим образом:

class RenameSemesterFromGeneralExams < ActiveRecord::Migration

  def change
    rename_column :general_exams, :semester, :semester_id
    change_column :general_exams, :semester_id, :integer
  end
end

Но, когда я запускаю rake db:migrate, он имеет ошибку:

==  RenameSemesterFromGeneralExams: migrating =================================
-- rename_column(:general_exams, :semester, :semester_id)
   -> 0.0572s
-- change_column(:general_exams, :semester_id, :integer)
rake aborted!
An error has occurred, this and all later migrations canceled:

PG::Error: ERROR:  column "semester_id" cannot be cast to type integer
: ALTER TABLE "general_exams" ALTER COLUMN "semester_id" TYPE integer

В моей таблице GeneralExam я уничтожил все данные. Итак, кто-нибудь может сказать мне, как я могу это сделать? Или я должен создать два файла миграции?

4b9b3361

Ответ 1

Вероятно, ваша проблема заключается в том, что semester содержит данные, которые нельзя преобразовать в integers. Вот почему вы получаете ошибку при трансляции.

Я подозреваю, что вам нужно сделать больше работы, чтобы сделать эту работу единственной вещью, которая приходит в голову - удалить столбец и создать новый с правильными значениями.

Но вы можете просто remove_column, а затем add_column за одну миграцию. Это должно работать безупречно.

Я также предлагаю сначала только add_column, затем выполните процесс сопоставления, в котором вы сопоставляете старое значение semester с новым semester_id, а затем удаляете столбец.

Имейте в виду, что вы можете выполнять манипуляции ActiveRecord внутри своей миграции. Таким образом, вы можете разместить там этот код.

Ответ 2

Это работает с Rails 4

def change
  rename_column :general_exams, :semester, :semester_id
  change_column :general_exams, :semester_id, :integer
end

Ответ 3

Эта ошибка возникает из-за того, что в таблицах (или значениях по умолчанию, возможно...) есть существующие данные, которые PG не знает, как преобразовать из строки в целое. Либо избавитесь от данных, либо сообщите PG, как вы хотите его преобразовать, используя PG-специфическую команду SQL (я думаю, вам нужно USING) и execute. См. Руководства Rails при переносе.