ruby-on-rails - framework - tutorial django
Cómo cambiar el nombre de una columna y cambiar su tipo por migración al mismo tiempo (4)
En mi tabla general_exams
, tengo una columna llamada semester
, el tipo es string
. Ahora quiero cambiar su nombre a semester_id
, el tipo es integer
. He leído sobre la migración y tiene transformaciones disponibles:
- rename_column (table_name, column_name, new_column_name): Renombra una columna pero mantiene el tipo y el contenido.
- change_column (table_name, column_name, type, options): cambia la columna a un tipo diferente usando los mismos parámetros que add_column.
Entonces, creo mi archivo de migración así:
class RenameSemesterFromGeneralExams < ActiveRecord::Migration
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, :integer
end
end
Pero, cuando ejecuto rake db:migrate
, tiene un error:
== 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
En mi mesa GeneralExam, destruí todos los datos. Entonces, cualquiera puede decirme cómo puedo hacer eso? ¿O debo crear dos archivos de migración?
Espero que esta ayuda
class ModifyColumnTables def change remove_column :posts, :old_column add_column :posts, :new_column, :type_of_column end end
Este error se debe a que hay datos existentes en las tablas (o valores predeterminados, tal vez ...) que PG no sabe cómo convertir de cadena a entero. Deshazte de los datos o dile a PG cómo quieres convertirlos, utilizando el SQL específico de PG (creo que querrás USING
) y execute
comando de migración. Ver guías de rieles sobre migraciones.
Esto funciona a partir de Rails 4.
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, :integer
end
Su problema probablemente sea que el semester
contiene datos que no se pueden convertir a integers
. Es por eso que obtienes un error de lanzamiento.
Sospecho que necesita hacer más trabajo para hacer que esto funcione, ya que lo único que viene a la mente es eliminar la columna y crear una nueva con los valores correctos.
Pero simplemente puede eliminar_column y luego agregar_column en una migración. Eso debería funcionar perfectamente.
También sugeriría que solo agregue primero una columna, luego realice el proceso de mapeo donde asigne el valor del semester
al nuevo semester_id
y luego suelte la columna.
Tenga en cuenta que puede realizar manipulaciones de ActiveRecord dentro de su migración. Así que puedes poner ese código ahí.