web-dev-qa-db-fra.com

Quel est le meilleur moyen de résoudre les migrations orphelines de Rails?

J'ai changé de branche dans un projet et chacune d'entre elles a une migration différente ... Voici le scénario:

$ rake db: migrate: status

 Status   Migration ID    Migration Name
--------------------------------------------------
   ...
   up     20130307154128  Change columns in traffic capture
   up     20130311155109  Remove log settings
   up     20130311160901  Remove log alarm table
   up     20130320144219  ********** NO FILE **********
   up     20130320161939  ********** NO FILE **********
   up     20130320184628  ********** NO FILE **********
   up     20130322004817  Add replicate to root settings
   up     20130403190042  ********** NO FILE **********
   up     20130403195300  ********** NO FILE **********
   up     20130403214000  ********** NO FILE **********
   up     20130405164752  Fix ap hostnames
   up     20130410194222  ********** NO FILE **********

Le problème est que rake db:rollback ne fonctionne pas du tout à cause des fichiers manquants ...

Que dois-je faire pour pouvoir revenir en arrière et supprimer les messages NO FILE?

Btw, rake db:reset ou rake db:drop ne sont pas une option, je ne peux pas perdre les données d'autres tables ...

28
Adrian

J'ai fini par résoudre le problème comme ceci:

(1) Accédez aux branches contenant les fichiers de migration et restaurez-les. Ce n’est pas anodin lorsque vous avez plusieurs branches qui entraîneront de nombreux conflits si vous essayez de les fusionner. J'utilise donc ces commandes pour déterminer les branches de chaque migration Orphan.

Il me faut donc trouver la validation de la dernière modification de la migration.

git log --all --reverse --stat | grep <LASTEST_Orphan_MIGRATION_ID> -C 10

Je prends le hachage de commit et détermine quelle branche il appartient comme ceci:

git branch --contains <COMMIT_HASH>

Ensuite, je peux revenir à cette branche, effectuer une restauration et répéter ce processus pour tous les fichiers manquants.

(2) Exécuter les migrations: vérifiez la branche sur laquelle vous souhaitez enfin travailler et exécutez les migrations et vous devriez être prêt à partir.

Dépannage

J'ai également couru dans certains cas où les migrations orphelines avaient lieu sur des branches supprimées.

Pour résoudre ce problème, j'ai créé des fichiers de migration factices avec le même ID de migration que les fichiers manquants et les ai restaurés. Après cela, j'ai pu supprimer leurs migrations factices et avoir un statut de migration propre :)

Une autre alternative consiste à supprimer directement les fichiers manquants de la base de données:

delete from schema_migrations where version='<MIGRATION_ID>';
48
Adrian

Les migrations sont stockées dans votre base de données. Si vous souhaitez supprimer les migrations abandonnées, supprimez-les de la base de données.

Exemple pour Postgres:

  1. Psql ouvert:

    psql
    
  2. Connectez-vous à votre base de données:

    \c your_database
    
  3. Si vous êtes curieux, affichez schema_migrations:

    SELECT * FROM schema_migrations;
    
  4. Si vous êtes curieux, vérifiez si les migrations abandonnées sont présentes:

    SELECT version FROM schema_migrations WHERE version IN 
    ('20130320144219', '20130320161939', '20130320184628', '20130403190042',
     '20130403195300', '20130403214000', '20130410194222');
    
  5. Supprime-les:

    DELETE FROM schema_migrations WHERE version IN (<version list as above>);
    

Maintenant, si vous exécutez bundle exec rake db:migrate:status, vous verrez que les migrations orphelines ont été supprimées avec succès.

21
medik

Edit: Comme indiqué dans les commentaires, le texte suivant Laisse tomber votre base de données

Une approche plus simple qui a fonctionné pour moi (notez que cette commande lâchera la base de données et toutes vos données seront perdues): 

rake db:migrate:reset

..et alors:

rake db:migrate:status

Les orphelins devraient disparaître.

15
spandata

Vous pouvez fusionner les deux branches dans le maître pour que toutes les migrations soient disponibles. Si vous ne voulez vraiment pas ces migrations, mais souhaitez pouvoir l'annuler, vous pouvez éditer la table schema_migrations de votre base de données pour supprimer les lignes correspondant aux migrations pour lesquelles vous n'avez pas de fichiers. Cependant, cela posera des problèmes si vous passez ensuite à une autre branche avec des migrations différentes.

0
Whit Kemmey

En supposant que vous utilisiez Git, il devrait être relativement simple de saisir ces migrations et de les importer dans votre branche actuelle. Si vous avez un commit spécifique pour lequel vous voulez un fichier, vous pouvez utiliser:

git checkout <commit hash> <file_name>

(Merci à cette réponse )

Alternativement, vous pouvez vérifier à partir d'une branche spécifique HEAD:

git checkout <branch name> -- <file_name>

Selon cela blog post

En supposant qu'il s'agisse en fait des versions des migrations exécutées sur la base de données, il est conseillé de revenir en arrière.

0
mikeryz

Si les fichiers de migration sont vraiment manquants (par exemple, migration exécutée, oublié de restaurer la migration, puis fichier de migration supprimé avant la validation), j'ai été en mesure de reproduire la migration manquante comme suit:

  1. revenez dans l’historique git pour obtenir une copie du fichier schema.rb et enregistrez-le en dehors du dépôt git (git log; git checkout xxxxxx; cp schema.rb ~/schema_old.rb, git checkout master).
  2. lancez un diff sur les deux fichiers et copiez les commandes de migration dans un fichier de migration correspondant à l'ID de migration manquant (diff schema.rb ~/schema_old.rb > migration_file.rb; vi migration_file.rb
  3. Vérifier l'état de votre migration et la restauration (rake db:migrate:status; rake db:rollback; rake db:migrate:status;)
0
Taylored Web Sites