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 ...
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>';
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:
Psql ouvert:
psql
Connectez-vous à votre base de données:
\c your_database
Si vous êtes curieux, affichez schema_migrations:
SELECT * FROM schema_migrations;
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');
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.
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.
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.
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.
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:
git log; git checkout xxxxxx; cp schema.rb ~/schema_old.rb, git checkout master)
.diff schema.rb ~/schema_old.rb > migration_file.rb; vi migration_file.rb
) rake db:migrate:status; rake db:rollback; rake db:migrate:status;
)