2009-10-25 9 views
9

Lorsque vous travaillez sur un projet avec plusieurs autres personnes, il est courant d'avoir plusieurs personnes avec des zones différentes, telles que la base de données.Intégration continue et gestion de base de données

Mon défi est de savoir comment permettre à plusieurs personnes d'éditer le modèle de base de données dans un environnement d'intégration continue.

Un développeur a suggéré d'écrire un "script de version" dans lequel chaque modification était entrée dans un script .sql, avec un numéro de version que la base de données serait capable de détecter. Une nouvelle addition au modèle serait marquée dans ce fichier avec une version, et la base de données serait mise à jour une fois que le script aurait été soumis et qu'une version aurait été exécutée.

J'ai aussi entendu parler de Publisher/Subscriber ... et en lire un peu à ce sujet.

Comment gérez-vous cette situation dans votre travail quotidien et quelles suggestions pouvez-vous me donner pour que les modifications de la base de données soient aussi transparentes que possible?

** Modifier **

cadres de migration et les scripts de migration ont été mentionnés. Si vous avez une expérience pratique et que vous suggérez un cadre, cela serait également apprécié.

Répondre

19

Jeff Atwood dans Citant l'excellent Get Your Database Under Version Control après:

...

Je pensais à ce nouveau parce que mon ami et co-author K. Scott Allen vient d'écrire un brillant cinq parties série sur la philosophie et pratique de contrôle de version de base de données:

  1. Three rules for database work
  2. The Baseline
  3. Change Scripts
  4. Views, Stored Procedures and the Like
  5. Branching and Merging

...

Vraiment, la série vaut la lecture même si beaucoup d'entre vous semble spécialement intéressé par la 3ème partie. Et BTW, jetez un oeil à l'article Bulletproof Sql Change Scripts Using INFORMATION_SCHEMA Views mentionné dans la 3ème partie aussi. Vous le savez peut-être déjà, mais cela explique, entre autres bonnes pratiques, pourquoi il est important d'écrire des scripts de changement idempotent.

En ce qui concerne l'outillage, vous pouvez consulter UpToDater (code centrique), LiquiBase (basé sur XML) ou ... dbdeploy, un petit bijou basé sur les expériences réelles de développement de logiciels en ThoughtWorks. Ce n'est pas que les 2 premiers ne sont pas bons mais celui-ci est mon préféré (et est disponible pour Java, PHP ou .NET).

+2

Je l'avais upvote 18 fois si je n'étais pas limité à seulement 1 upvote: D – whaley

+1

Demandez à votre grand-mère de voter alors :) Plus sérieusement, heureux que vous le trouviez utile. –

+0

Merci pour le lien. Souhaitez-vous que le point # 1 dans les 3 règles ait plus de détails. C'est quelque chose que nous luttons maintenant. Définitivement plus facile à dire qu'à faire. – CodingWithSpike

1

Vérifiez les structures de migration. AFAIK, l'idée est venue des rails, mais les gens ont construit des cadres pour à peu près tout le reste à ce stade.

5

J'ai tendance à mieux fonctionner avec les scripts de 'migration', qui sont la prochaine étape d'un script simple versionné. Lors d'une migration, vous spécifiez les modifications apportées à la base de données (ajouts, suppressions, etc.) et également comment annuler les modifications effectuées par votre migration. Ceci est ensuite étiqueté avec une version d'une certaine forme qui ne sera pas incompatible avec d'autres développeurs. Un numéro de version particulièrement bon est l'heure actuelle (au format AAAAMMJJHHMMSS ou en secondes à partir de l'époque). C'est un bon choix car il est très peu probable que vous obteniez des conflits de versions et il est toujours très facile de voir si de nouvelles versions existent en raison de la nature strictement croissante de ces horodatages.

Remarque: Ceci est très influencé par le système de migration dans Rails. Pour plus de détails et d'idées, je recommande fortement d'examiner ce système.

migration Rails:

class CreateGroups < ActiveRecord::Migration 
    def self.up 
    create_table :groups do |t| 
     t.string :name 
     t.references :owner 

     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :groups 
    end 
end 

migration Doctrine:

class CreateGroups extends Doctrine_Migration 
{ 
    public function up() 
    { 
     // Create new author table 
     $columns = array('id' => array('type'   => 'integer', 
             'length'  => 4, 
             'autoincrement' => true), 
         'name' => array('type'   => 'string', 
             'length'  => 255), 
         'owner_id' => array('type' => 'integer', 
              'length' => 4)); 

    $this->createTable('groups', $columns, array('primary' => array('id'))); 
    } 

    public function down() 
    { 
    $this->dropTable('groups'); 
    } 
} 

(désolé pour le manque de horodatages dans la doctrine ... dans des rails l'appel horodatages ajoute dans created_at et updated_at champs à la table sont gérés automatiquement pour vous, je ne suis pas sûr d'un comportement similaire dans la doctrine, donc je les ai laissés de côté).

+1

J'aimerais voir un exemple de script de migration si vous en avez un? – CodeMonkey

+0

Je seconde l'exemple de demande. – Martin

+0

Je vais ajouter un exemple de migration de rails plus tard aujourd'hui, avec une migration de doctrine à peu près équivalente. – workmad3

1

Cela dépend.

S'il s'agit d'un produit publié dont vous parlez, les modifications de schéma doivent faire l'objet d'un suivi minutieux afin que vous puissiez planifier votre processus de mise à niveau. Il serait bon de commencer à y penser maintenant, donc le "script de version" a un certain sens. Mais la compatibilité amont/aval n'est généralement qu'une exigence visible par l'utilisateur, pas une exigence "entre compilations". Entre les versions, il serait logique de maintenir un script de mise à niveau qui modifie les tables de la base de données pour l'amener au nouveau schéma.

S'il s'agit d'un produit nouveau/inédit, que vous importe si quelqu'un change le schéma?Et pourquoi voudriez-vous même garder la base de données entre les builds d'intégration continue? Vous devriez être capable de régénérer toutes les données de test avec un test automatisé, de toute façon. Toute personne qui modifie le schéma doit également mettre à jour les tests. Pour un produit publié, vous souhaiterez probablement disposer d'un ensemble de tests pouvant traiter une base de données "version 1.0", afin de vous assurer qu'il peut être mis à niveau avec succès vers la "version 1.1" (par exemple).

0

Nous scriptons tout dans Subversion et le vérifions dans le projet comme n'importe quel autre code. Tous les déploiements de base de données sont effectués à partir de scripts extraits du système de contrôle de source. Si deux personnes travaillent sur le même script (ce qui est assez rare), Subversion vous permettra de fusionner les deux scripts.

1

La pile technologique (y compris la base de données utilisée) n'a pas été décrite dans la question, ce qui est très pertinent pour la solution la mieux adaptée.

Une solution de migrations Java-centric très populaire est Flyway. DBUp est très similaire mais se concentre sur la pile .NET.

Ici, chez Redgate, nous offrons ReadyRoll, qui s'intègre étroitement dans Visual Studio et fonctionne exclusivement avec SQL Server.

Questions connexes