139 votes

Comment travailler avec les branches Git et les migrations Rails ?

Je travaille sur une application rails avec un grand nombre de branches git et beaucoup d'entre elles incluent des migrations de données. Nous essayons d'être prudents, mais il arrive qu'un morceau de code dans le master demande une colonne qui a été supprimée/renommée dans une autre branche.

  1. Quelle serait une bonne solution pour "coupler" les branches git avec les états de la DB ?

  2. Quels seraient ces "états" en réalité ?

    Nous ne pouvons pas simplement dupliquer une base de données si elle a une taille de quelques Go.

  3. Et que doit-il se passer avec les fusions ?

  4. La solution s'appliquerait-elle également aux bases de données noSQL ?

    Nous utilisons actuellement MySQL, mongodb et redis.


EDIT : On dirait que j'ai oublié de mentionner un point très important, je ne suis intéressé que par la environnement de développement mais avec des bases de données volumineuses (de l'ordre de quelques Go).

0 votes

Que faites-vous pour avoir un environnement qui exécute votre branche maîtresse dont la base de données peut être modifiée par d'autres branches ? Je ne comprends pas quel est votre flux de travail ou pourquoi vous pensez avoir besoin de garder les branches en synchronisation avec des bases de données particulières.

3 votes

Disons que nous avons une table dans notre base de données avec des clients (nom, email, téléphone) et dans une branche nous avons divisé une des colonnes (nom -> prénom + nom). Jusqu'à ce que nous fusionnions la branche avec le master, le master et toutes les autres branches basées sur celui-ci échoueront.

70voto

Andy Lindeman Points 7213

Lorsque vous ajoutez une nouvelle migration dans n'importe quelle branche, exécutez rake db:migrate et de valider la migration et db/schema.rb

Si vous faites cela, en cours de développement, vous pourrez passer à une autre branche qui a un ensemble différent de migrations et simplement exécuter rake db:schema:load .

Notez que cela recréer toute la base de données, et les données existantes seront perdues .

Vous ne voudrez probablement exécuter la production qu'à partir d'une seule branche avec laquelle vous êtes très prudent, donc ces étapes ne s'appliquent pas ici (exécutez juste rake db:migrate comme d'habitude ici). Mais dans le cadre d'un développement, il ne devrait pas être difficile de recréer la base de données à partir du schéma, ce qui est le but de l'opération. rake db:schema:load fera l'affaire.

5 votes

Je pense que cela ne résoudra que le problème du schéma, les données seront perdues à chaque migration descendante et ne seront jamais revues. Serait-ce une bonne idée d'enregistrer une sorte de patch de données de base qui serait sauvegardé lors de la sortie d'une branche et un autre qui serait chargé lors de l'entrée dans une autre branche ? Les patchs ne devraient contenir que les données qui seraient perdues lors de la migration vers le bas (migrations).

4 votes

Si vous voulez charger des données, utilisez db/seeds.rb Il ne devrait pas être trop dévastateur de détruire votre base de données de développement si vous y configurez des données de départ raisonnables.

0 votes

Pas besoin de nuke quoi que ce soit. voir ma solution ci-dessous. Sachez simplement que vous aurez de nombreuses instances et que lorsque vous changerez de branche, les données ne seront pas présentes. C'est tout à fait normal si vous développez avec des tests.

24voto

ndp Points 8959

Si vous avez une grande base de données que vous ne pouvez pas reproduire facilement, je vous recommande d'utiliser les outils de migration normaux. Si vous souhaitez un processus simple, voici ce que je vous recommande :

  • Avant de changer de branche, faites un retour en arrière ( rake db:rollback ) à l'état précédant le point de branchement. Puis, après avoir changé de branche, exécutez db:migrate . C'est mathématiquement correct, et tant que vous écrivez down scripts, ça va marcher.
  • Si vous oubliez de le faire avant de changer de branche, vous pouvez en général revenir en arrière, faire un retour en arrière et changer à nouveau de branche, donc je pense qu'en tant que flux de travail, c'est faisable.
  • Si vous avez des dépendances entre des migrations dans différentes branches... eh bien, vous devrez réfléchir sérieusement.

2 votes

Vous devez garder à l'esprit que toutes les migrations ne sont pas réversibles, cela dit, la première étape suggérée n'est pas garantie de réussir. Je pense qu'en environnement de développement, une bonne idée serait d'utiliser rake db:schema:load y rake db:seed comme l'avait dit @noodl.

0 votes

@pisaruk Je sais que vous avez répondu à cette question il y a six ans, mais en lisant, je suis curieux de savoir quel serait un exemple de migration non réversible. J'ai du mal à imaginer une situation. Je suppose que le plus simple serait une colonne abandonnée contenant un tas de données, mais cela pourrait être "inversé" pour avoir une colonne vide ou une colonne avec une certaine valeur par défaut. Pensiez-vous à d'autres cas ?

1 votes

Je pense que vous avez répondu à votre propre question ! Oui, une colonne abandonnée est un bon exemple. Ou une migration de données destructive.

17voto

Jon Lemmon Points 618

Voici un script que j'ai écrit pour basculer entre des branches qui contiennent des migrations différentes :

https://gist.github.com/4076864

Il ne résoudra pas tous les problèmes que vous avez mentionnés, mais avec un nom de branche, il le fera :

  1. Annulez toutes les migrations sur votre branche actuelle qui n'existent pas sur la branche donnée.
  2. Abandonner toute modification du fichier db/schema.rb
  3. Vérifier la branche donnée
  4. Exécuter toutes les nouvelles migrations existant dans la branche donnée
  5. Mettez à jour votre base de données de test

Je me retrouve tout le temps à faire cela manuellement sur notre projet, alors j'ai pensé qu'il serait bien d'automatiser le processus.

1 votes

Ce script fait exactement ce que je veux faire, j'aimerais bien le voir mis dans un crochet de caisse automatique.

1 votes

C'est juste une info, j'ai bifurqué de votre gist et l'ai transformé en un crochet post-checkout : gist.github.com/brysgo/9980344

0 votes

Dans votre script, avez-vous vraiment voulu dire git checkout db/schema.rb ou vous voulez dire git checkout -- db/schema.rb ? (c'est-à-dire avec des doubles tirets)

4voto

noodl Points 8992

Peut-être devriez-vous prendre cela comme un indice que votre base de données de développement est trop grande ? Si vous pouvez utiliser db/seeds.rb et un ensemble de données plus petit pour le développement, votre problème peut être facilement résolu en utilisant schema.rb et seeds.rb de la branche actuelle.

Cela suppose que votre question concerne le développement ; je ne vois pas pourquoi vous auriez besoin de changer régulièrement de branche en production.

0 votes

Je ne savais pas que db/seeds.rb Je vais y jeter un coup d'oeil.

3voto

Tabrez Points 942

Je me débattais avec le même problème. Voici ma solution :

  1. Assurez-vous que schema.rb et toutes les migrations sont validées par tous les développeurs.

  2. Il devrait y avoir une personne/machine pour les déploiements vers la production. Appelons cette machine la "merge-machine". Lorsque les modifications sont transférées vers la machine de fusion, la fusion automatique de schema.rb échoue. Aucun problème. Remplacez simplement le contenu avec le contenu précédent de schema.rb (vous pouvez mettre une copie de côté ou l'obtenir de github si vous l'utilisez ...).

  3. Voici l'étape importante. Les migrations de tous les développeurs seront maintenant disponibles dans le dossier db/migrate. Allez-y et exécutez bundle exec rake db:migrate. Cela mettra la base de données sur la machine de fusion au même niveau que tous les changements. Il va également régénérer schema.rb.

  4. Commit et pousse les changements vers tous les dépôts (distants et individuels, qui sont également distants). Vous devriez avoir terminé !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X