mysql - inmigración - error 1072 key column doesn''t exist in table
La migración para crear tablas genera Mysql2:: Error: la tabla no existe (4)
Escribí una migración con lo siguiente:
class CreateTableSomeTable < ActiveRecord::Migration[5.1]
def change
create_table :some_tables do |t|
t.references :user, foreign_key: true
t.references :author, references: :user, foreign_key: true
t.text :summary
end
end
end
Es una migración básica que está creando una tabla de base de datos. Sin embargo: cuando ejecuto rails db:migrate
un mensaje de error muy extraño anula la migración:
Mysql2 :: Error: la tabla ''my_database.some_tables'' no existe: MOSTRAR CAMPOS COMPLETOS DE ''some_tables''
Es como si el error estuviera diciendo que no puede crear la tabla porque la tabla existe, lo que no tiene sentido.
Cosas que he visto y probado:
- revisó el database.yml que parece estar bien. Nada ha cambiado, y recientemente ejecuté otras migraciones muy bien (aunque no hay migraciones que hayan creado tablas de base de datos)
- Ejecutamos el
bundle
para asegurar que todas las gemas fueron instaladas -
schema.rb
archivoschema.rb
,schema.rb
crear la base de datos con datos de otra copia y ejecutérake db:schema:dump
para recrear el archivoschema.rb
. Intenté ejecutar la migración de nuevo y todavía obtuve el mismo error.
Estoy utilizando rails 5.1.1
y mysql2 0.4.6
¿Algún consejo sobre cómo puedo conseguir que se ejecute la migración?
Descubrí un trabajo alrededor, pero todavía es muy desconcertante para mí.
El mensaje de error en el archivo de registro no señalaba exactamente el problema. Por alguna razón, podría ser rails 5.1.1
o mysql2 0.4.6
, pero no le gusta usar references
dentro del bloque create_table
por alguna razón. Muy extraño porque me ha funcionado en el pasado.
Así que cambié la migración de esto:
class CreateTableSomeTable < ActiveRecord::Migration[5.1]
def change
create_table :some_tables do |t|
t.references :user, foreign_key: true
t.references :author, references: :user, foreign_key: true
t.text :summary
end
end
end
A esto:
class CreateTableSomeTable < ActiveRecord::Migration[5.1]
def change
create_table :some_tables do |t|
t.integer :user_id
t.integer :author_id
t.text :summary
end
end
end
Y funcionó.
Es muy extraño porque las references
funcionan bien con sqlite3
(probé esto generando una aplicación ficticia, ejecuté un comando de andamio con una columna de references
y corrí rails db:migrate
y todo funcionó).
El gran problema con la migración de ActiveRecord 5.1 es que ahora se espera que el ID sea BIGINT en lugar de INT, por lo que cuando agrega una columna que se refiere a otra tabla creada antes de los rieles 5.1, espera que el tipo de columna sea BIGINT, pero en lugar de eso solo sea un INT. De ahí el error. La mejor solución es simplemente modificar su migración y cambiar el tipo de la columna a int.
class CreateTableSomeTable < ActiveRecord::Migration[5.1]
def change
create_table :some_tables do |t|
t.references :user, foreign_key: true, type: :int
t.references :author, references: :user, foreign_key: true
t.text :summary
end
end
eso debería funcionar.
Esto me volvió loco, creo que estaba viendo una razón diferente para esto que lo que otros sugirieron. En mi caso, sucedió porque los nombres de mis archivos de migración no coincidían exactamente con la clase de migración. Por ejemplo, tuve un archivo de migración llamado 20171205232654_bonus.rb
pero dentro de la clase se declaró como class CreateBonus < ActiveRecord::Migration[5.1]
. Una vez que cambié el nombre del archivo a 20171205232654_create_bonus.rb
todo funcionó.
Esto podría tener algo que ver con el hecho de que solo he estado creando migraciones, no andamios completos, y tal vez hice algo mal. Realmente no sé cómo terminé con ese desajuste.
Recibí un error similar al intentar crear un nuevo modelo que tiene una referencia a un modelo existente que se creó antes de migrar a Rails 5.1.
Aunque el mensaje de error no era muy claro al respecto, en mi caso resultó que el problema era la falta de coincidencia de tipo de datos entre la clave principal del modelo antiguo y la clave externa del nuevo modelo (MySQL no lo permite). Fue así porque desde Rails 5.1, el tipo de datos predeterminado de todas las claves primarias y externas es bigint, pero para el modelo anterior el tipo de clave primaria todavía era entero.
Resolví esto convirtiendo todas las claves primarias y externas de los modelos actuales a bigint, por lo que puedo usar los nuevos valores predeterminados de Rails y olvidarme de ellos.
Una solución alternativa también podría ser especificar el tipo de entero para las nuevas claves foráneas para que coincidan con el tipo de clave principal de los modelos anteriores. Algo como lo siguiente:
class CreateUserImages < ActiveRecord::Migration[5.1]
def change
create_table :user_images do |t|
t.references :user, type: :integer, foreign_key: true
t.string :url
end
end
end