web-dev-qa-db-fra.com

Migration pour créer une table soulève Mysql2 :: Error: La table n'existe pas

J'ai écrit une migration avec les éléments suivants:

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

C'est une migration de base qui crée une table de base de données. Cependant, lorsque je lance Rails db:migrate, un message d'erreur très étrange interrompt la migration:

Mysql2 :: Error: La table 'my_database.some_tables' n'existe pas: SHOW FULL FIELDS FROM 'some_tables'

C'est comme si l'erreur disait qu'elle ne peut pas créer la table parce que la table existe, ce qui n'a pas de sens. 

Choses que j'ai regardées et essayées:

  • examiné le database.yml qui semble bien. Rien n'a changé et j'ai récemment exécuté d'autres migrations sans problème (même si aucune migration n'a créé de tables de base de données).
  • a lancé bundle pour s'assurer que toutes les gemmes ont été installées
  • supprimé le fichier schema.rb, recréé la base de données avec les données d'une autre copie, et j'ai exécuté rake db:schema:dump pour recréer le fichier schema.rb. J'ai essayé d'exécuter à nouveau la migration et j'ai toujours la même erreur. 

J'utilise Rails 5.1.1 ainsi que mysql2 0.4.6

Des conseils sur la manière dont je peux faire fonctionner la migration?

17
Neil

J'ai imaginé un travail, mais c'est toujours très déroutant pour moi. 

Le message d'erreur dans le fichier journal ne signalait pas exactement le problème. Pour une raison quelconque, il peut s'agir de Rails 5.1.1 ou de mysql2 0.4.6, mais il n'aime pas utiliser references dans le bloc create_table pour une raison quelconque. Très étrange parce que cela a fonctionné pour moi dans le passé.

J'ai donc changé la migration à partir de ceci:

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

Pour ça:

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

Et ça a fonctionné. 

C'est très étrange parce que references fonctionne très bien avec sqlite3 (je l'ai testé en générant une application factice, en exécutant une commande d'échafaud avec une colonne references et en exécutant Rails db:migrate

5
Neil

Une erreur similaire s'est produite lors de la création d'un nouveau modèle comportant une référence à un modèle existant créé avant la migration vers Rails 5.1.

Bien que le message d'erreur ne soit pas très clair à ce sujet, dans mon cas, il s'est avéré que le problème était une incompatibilité de type de données entre la clé primaire de l'ancien modèle et la clé étrangère du nouveau modèle (MySQL ne le permet pas). En effet, depuis Rails 5.1, le type de données par défaut de toutes les clés primaires et étrangères est bigint, mais pour l'ancien modèle, le type de clé primaire était toujours entier.

J'ai résolu ce problème en convertissant toutes les clés primaires et étrangères des modèles actuels en bigint, afin que je puisse utiliser les nouvelles valeurs par défaut de Rails et l'oublier. 

Une solution de contournement pourrait également consister à spécifier un type entier pour les nouvelles clés étrangères afin qu'elles correspondent au type de clés primaires des anciens modèles. Quelque chose comme ce qui suit:

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
28
Marcis Viskints

Le gros problème avec la migration 5.1 d’ActiveRecord est que, maintenant, les id sont censés être BIGINT au lieu d’INT. Par conséquent, lorsque vous ajoutez une colonne faisant référence à une autre table créée avant Rails 5.1, le type de colonne doit être BIGINT, D'où l'erreur .. La meilleure solution consiste simplement à modifier votre migration et à changer le type de la colonne en 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

cela devrait fonctionner.

8
helmutrs

Cela m'a rendu fou, je pense que je voyais une raison différente de celle suggérée par les autres. Dans mon cas, cela s'est produit parce que les noms de mes fichiers de migration ne correspondaient pas exactement à la classe de migration correspondante. Par exemple, j'avais un fichier de migration nommé 20171205232654_bonus.rb mais à l'intérieur de la classe, il a été déclaré en tant que class CreateBonus < ActiveRecord::Migration[5.1]. Une fois que j'ai changé le nom du fichier en 20171205232654_create_bonus.rb, tout a fonctionné.

Cela pourrait avoir un lien avec le fait que je n'ai créé que des migrations, pas des échafaudages complets, et peut-être que j'ai fait quelque chose de mal. Je ne sais vraiment pas comment je me suis retrouvé avec cette inadéquation. 

0
Adam Ehven