66 votes

Comment gérer les migrations dans un projet avec plusieurs branches?

J'ai un ASP.NET MVC3 projet qui utilise Entity Framework 4.3 avec le code-première approche. J'ai utiliser les Migrations de garder la base de données à jour.

Le projet est sous contrôle des sources et j'ai un certain nombre de branches. Ce que je viens de réaliser qu'il y aura un problème lorsque je wan pas de fusionner l'une de mes branches dans le maître. Depuis que j'ai créé à la migration des fichiers dans les deux branches, il y aura chevauchement des migrations lorsque je de fusion, qui sera probablement la cause de conflits.

Est-il une bonne façon de gérer les Migrations dans un projet avec plusieurs branches?

Mise à jour

Un autre moyen serait de fusionner, puis de les supprimer tous à la migration des fichiers créés tandis que les branches ont été séparés, et puis créer un nouveau fichier de migration qui contient toutes les modifications dans le temps, la direction générale a été créée jusqu'à ce qu'il a été fusionnée dans. Ce serait le travail de la dev-environnement où vous pouvez faire un dump de la base de données et re-construire avec tous les migrations des fichiers. Le problème serait alors de l'environnement. Puisque vous ne pouvez pas revenir à l'époque de la branche a été créée sans le risque de perdre des données, il y aura un conflit lorsque vous essayez d'utiliser votre nouvelle migration-fichier de mise à jour de la base de données.

20voto

pcguru Points 1535

Je pense que l'on a accepté la réponse est incorrecte. Il y a une bien meilleure solution pour le traitement de l'entité cadre de la migration des conflits de fusion sur une question similaire.

Tout ce que vous devez faire après une opération de fusion est de re-échafaudage les méta-données de la migration dans la branche cible. Qui est vous n'avez pas rescaffold le code, il suffit de l'état dans le resx-fichier.

add-migration [the_migration_to_rescaffold_metadata_for]

Cette procédure échoue, si différente de la migration dans la fusion ont changé la base de données de telle manière que la migration n'est plus praticable ou donne un résultat inattendu. Cela étant dit, je pense que pour être un cas très rare que la plupart des migrations devrait être auto-généré, ou au moins de ne pas être dépendant sur d'autres tables qui ne sont pas modifiées au cours de la migration elle-même. Mineur, mais un être conscient.

L'un de ces cas pourraient être fxp (je ne pouvais pas penser à un meilleur exemple)

  • Colonne foo est un int et des lignes contiennent [0, 1, 2]

  • La Migration de branche, Un changement de foo boolean (0 deviendra faux automatiquement et > 0 deviendra vrai)

  • La Migration de B à partir de la branche B de changement de foo à la chaîne. Il attend un int, mais il est un booléen, la migration va réussir si. Les données seront perdues depuis quand la migration B a été créé les lignes contiendrait ["0", "1", "2"]. Lors de la migration d'Une altération de la colonne de booléens (et l'a fait avec succès et avec des résultats escomptés) les lignes contiennent à présent ["0", "1", "1"] au lieu de Migration et B aura une autre conséquence de ce qui a été observé dans la Branche B.

Il ya probablement plus de cas où les choses pourraient aller mal avec la solution. Mais si les migrations vers le haut/vers le bas code ne dépend pas de choses ont changé par une autre migration dans la fusion, il devrait bien fonctionner pour mettre à jour les métadonnées dans les migrations.

19voto

Bill Yang Points 712

J'ai trouvé un assez simple solution basée sur @Ladislav Mrnka de réponse. Cela fonctionne avec live de l'environnement[1], vous avez juste à être prudent de ne pas modifier n'importe quel déploiement des migrations.

  1. Avant de Fusion, de prendre note de la migration que vous avez ajouté (MyMigration), et sa migration précédente (BaseMigration)

  2. Fusion des branches de git

  3. Ouvrez le Gestionnaire de Package de la Console, et de l'exécution: mise à JOUR de la BASE de données -TargetMigration:BaseMigration. Cela permettra de revenir à votre base de données de l'état avant tout de conflit migrations sont appliquées

  4. Supprimer votre local migration (MyMigration)

  5. Exécution: mise à JOUR de la BASE de données. Ceci sera appliqué à toutes les nouvelles migrations fait dans d'autres branches.

  6. Exécuter: AJOUTEZ-MIGRATION MyMigration. Cela re-générer votre local de la migration fondée sur l'état actuel de la base de données, tels que git -git rebase.

  7. Exécution: mise à JOUR de la BASE de données. Mise à jour de la base de données avec vous les migrations locales.

Cela fonctionne aussi si vous avez plusieurs locaux migrations, mais il va fusionner en un seul.

[1] en travaillant avec l'environnement réel, je veux dire que le migration peut être appliquée à vivre de l'environnement qui peut déjà avoir certaines ou toutes les autres branches transferts appliqués. Les étapes se sont purement à des fins de développement.

13voto

Ladislav Mrnka Points 218632

La fusion des migrations est à mon humble avis de tâches manuelles. Le cadre de la migration de code est généré automatiquement et nous avons l'habitude de ne pas fusionner code généré automatiquement - au lieu de cela, nous courons autogeneration de nouveau après la fusion.

Jusqu'à ce que ADO.NET l'équipe fournit une recommandation, je voudrais suivre un principe simple:

  • Avant de procéder à la fusion de rétablir la base de données pour la version utilisée avant la ramification
  • Fusionner vos branches
  • Exclure les classes de migration créé après la ramification de la fusion de l'assemblée
  • Ajouter une nouvelle migration de fusion de la base de code qui va migrer votre base de données dans l'état antérieur à la ramification de l'état après la fusion de branches
  • Si votre exclus de la migration classes contiennent un certain degré de personnalisation de fusion à la nouvelle classe de migration
  • Exécuter la migration pour migrer votre base de données actuelle version fusionnée

Si vos branches contenait plusieurs étapes de migration (version), vous perdrez et vous allez vous retrouver avec deux versions - avant de ramification et après la fusion.

Edit:

Il ne fonctionne pas dans l'environnement direct. Le problème ici serait le processus de développement lui-même. Si vous avez de l'environnement réel vous devriez garder sa branche intacte (à l'exception de quelques corrections mineures). Si vous continuez dans cette direction, avec un déploiement en production et dans le même temps, de vous construire une autre version dans la branche distincte sans intégration continue (= continu fusion des modifications apportées à la branche intégrer votre nouveau développement avec le code principal de la base de), vous avez un gros problème. Je pense que les migrations en général ne peut pas gérer cela.

La seule solution dans ce cas serait probablement retrait de toutes les migrations de la fusion de la solution et la suppression d' MigrationHistory table de la base de données. Que vous pouvez vous permettre les migrations sur le projet de nouveau et ajouter le premier départ pour l'utilisation de votre base de données actuelle comme point de départ = pas de retour à la précédente version, car aucune information sur les migrations antérieures existent.

4voto

LavaEater Points 61

J'ai mis une certaine pensée dans ce et j'espère que je vais contribuer aux différentes opinions et les pratiques présentées ici.

Pensez à ce que votre local migrations représentent réellement. Lorsque l'on travaille en local avec un dev de base de données, j'utilise les migrations à la mise à jour de la base de données de la manière la plus pratique possible lors de l'ajout de colonnes, etc pour les tableaux, l'ajout de nouvelles entités, etc.

Donc, Ajoutez-le contrôle des mouvements Migratoires mon modèle actuel (appelons-le modèle b) à l'encontre de mon précédent modèle (modèle a) et génère une migration pour aller de a => b dans la base de données.

Pour moi, il fait très peu de sens pour essayer et fusionner mes migrations avec quelqu'un elses migrations, si tout le monde a en effet leur propre base de données et il n'existe alors une sorte de scène / test / dev / base de données de production les serveurs de l'organisation. Tout cela dépend de la façon dont l'équipe a mis en place, mais il est logique de les isoler les uns des autres à partir de variations que d'autres gens à faire si vous voulez vraiment travailler de manière distribuée.

Eh bien, si vous travaillez distribués et ont une certaine entité, d'une Personne, par exemple, que vous travaillez sur. Pour quelque raison, beaucoup d'autres personnes sont également de travailler sur elle. Donc, vous pouvez ajouter et supprimer des propriétés sur la Personne en tant que de besoin pour votre histoire en particulier dans le sprint (nous travaillons tous agile ici, n'est-ce pas?), comme le numéro de Sécurité Sociale que vous avez d'abord fait en un nombre entier, car vous n'êtes pas vif, puis à une chaîne de caractères etc.

Vous ajoutez FirstName Et LastName.

Vous êtes alors terminé et que vous avez dix bizarre en haut et en bas des migrations (vous avez probablement supprimé certains d'entre eux tout en travaillant depuis qu'ils étaient tout simplement de la merde) et vous chercher quelques modifications de la centrale repo Git. Wow. Votre collègue Bob a également besoin de quelques noms, peut-être devriez vous ai parlé les uns aux autres?

De toute façon, il a ajouté NameFirst et NameLast, je suppose que... que faites-vous? Eh bien, vous fusionner, refactoriser, changement de sorte qu'il est plus sain d'esprit des noms... comme FirstName et LastName, de l'exécution des tests et vérifier son code, et puis vous poussez à la centrale.

Mais ce sur les migrations? Eh bien, maintenant serait le moment de faire une migration de déplacer la centrale de pensions de titres, ou de la branche "test" plus précisément, contiennent un joli petit migration à partir de son modèle de a => b. Cette migration sera un et un seul de la migration, pas dix étranges.

Vous voyez de quoi je veux en venir? Nous travaillons avec de belles petites poco et les comparaisons d'entre eux constituent la migration. Donc, à nous de ne pas fusionner les migrations à tous, à mon avis, nous devrions avoir les migrations par branche ou quelque chose comme ça.

En fait, nous avons même besoin de créer de la migration dans la branche après la fusion? Oui, si cette base de données est automatiquement mise à jour, nous en avons besoin.

Dois travailler un peu plus, ce sont mes pensées sur ce, au moins.

2voto

Eamon Nerbonne Points 21663

Pensez à utiliser une bibliothèque de migration différente qui ne provoque pas ces conflits, telle que FluentMigrator ou Migrator.NET.

Je ne pense pas que les migrations EF soient vraiment prêtes à l'emploi général avec les branches et les fusions - c'est beaucoup de travail et trop facile de faire de mauvaises erreurs.

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