Wie werden mehrere db alter Skripte behandelt, die von verschiedenen Git-Feature-Zweigen kommen?

8

Ein bisschen komplex zu beschreiben, aber ich werde mein Bestes geben. Grundsätzlich verwenden wir den Git-Workflow, dh wir haben folgende Zweige:

  • Produktion, die die Live-Branche ist. Alles läuft in der Live-Web-Umgebung.
  • Integration, in der alle neuen Funktionen integriert sind. Dieser Zweig wird jede Woche mit der Produktion zusammengeführt.
  • ein oder mehrere Feature-Zweige, in denen Entwickler oder Entwicklerteams neue Funktionen entwickeln. Danach fügen Entwickler ihren Feature-Zweig zur Integration hinzu.

Also, nichts wirklich Komplexes hier. Da es sich bei unserer Anwendung jedoch um eine Webanwendung handelt, die mit einer MySQL-Datenbank ausgeführt wird, erfordern neue Funktionen häufig Änderungen am Datenbankschema. Um dies zu automatisieren, verwenden wir dbdeploy, mit dem wir alternative Scripts für eine bestimmte Nummer erstellen können. Z.B. 00001.sql, 00002.sql usw. Beim Zusammenführen mit dem Integrationszweig überprüft dbdeploy, welche Alterskripte eine höhere Anzahl als die zuletzt ausgeführte Version in dieser spezifischen Datenbank haben und führt diese aus.

Nehmen Sie nun Folgendes an. - Die Integration hat Skripte bis 00200.sql verändert. Alle diese werden in der Integrationsdatenbank ausgeführt. - Entwickler John hat einen Feature-Zweig featureX, der erstellt wurde, als die Integration noch 00199.sql als höchstes Alter-Script hatte.

John erstellt 00200.sql wegen einiger erforderlicher Änderungen des Datenbankschemas.

Irgendwann wird John seine Modifikationen wieder in den Integrationszweig einfügen. John wird einen Merge-Konflikt bekommen und wird sehen, dass seine 00200.sql bereits in der Integration existiert. Das heißt, er muss die in Konflikt stehende Datei öffnen, seinen Inhalt extrahieren, diese Datei wieder auf "meine" setzen (den ursprünglichen Zustand wie bei der Integration) und seinen eigenen Inhalt in eine neue Datei einfügen.

Jetzt, da wir mit zehn Entwicklern arbeiten, bekommen wir diese Situation täglich. Und obwohl wir die Gründe dafür verstehen, ist es manchmal sehr umständlich. John benennt sein Skript um, führt ein Merge-Commit zur Integration durch, schiebt die Änderungen an den Upstream, nur um zu sehen, dass jemand anderes bereits 00201.sql erstellt hat, was John dazu zwingt, den Prozess erneut durchzuführen.

Sicherlich müssen mehr Teams den Git-Workflow verwenden und ein Datenbank-Änderungsmanagement-Tool für die Automatisierung von Datenbankschema-Änderungen verwenden.

Kurz gesagt, meine Fragen sind:

  • Wie kann man Datenbankschemaänderungen automatisieren, wenn man an verschiedenen Feature-Zweigen arbeitet, die auf verschiedenen Instanzen derselben db arbeiten?
  • Wie kann man Merge-Konflikte immer verhindern und trotzdem eine feste Reihenfolge in den ausgeführten alter-Skripten haben? Z.B. 00199.sql muss vor 00200.sql ausgeführt werden, da 00200.sql von etwas abhängt, das in 00199.sql.
  • erledigt wurde

Andere Tipps sind natürlich sehr willkommen.

    
Tonni Tielens 09.07.2014, 15:56
quelle

5 Antworten

4

Rails hat das getan, mit genau den Problemen, die Sie beschreiben. Sie änderten sich in das folgende Schema: Die Dateien (Schienen nennt sie Migrationen) sind mit einem utc-Zeitstempel versehen, wann die Datei erstellt wurde, zB

%Vor%

(Der zweite Teil des Namens trägt nicht zur Reihenfolge bei).

Rails zeichnet die Zeitstempel aller ausgeführten Migrationen auf. Wenn Sie ihn auffordern, ausstehende Migrationen auszuführen, wählt er alle Migrationsdateien aus, deren Zeitstempel nicht in der Liste der bereits ausgeführten Migrationen enthalten ist, und führt sie in numerischer Reihenfolge aus.

Sie werden keine Zusammenführungskonflikte mehr erhalten, wenn nicht zwei Personen genau zur selben Zeit einen erstellen.

Dateien werden immer noch in der Reihenfolge ausgeführt, in der Sie sie geschrieben haben, aber möglicherweise mit der Arbeit eines anderen verschachtelt. Theoretisch können Sie immer noch Probleme haben - zB entscheidet Entwickler a, eine Tabelle umzubenennen, für die ich eine Spalte hinzugefügt habe. Das ist viel weniger üblich als 2 Entwickler, die beide Änderungen an der Datenbank vornehmen, und Sie hätten Probleme, die Schemaänderungen nicht zu berücksichtigen. Ich habe gerade Code geschrieben, der eine nicht mehr existierende Tabelle abfragt - irgendwann werden Entwickler, die an verwandten Dingen arbeiten miteinander reden!

    
Frederick Cheung 23.07.2014 06:18
quelle
2

Einige Vorschläge:

1 - Werfen Sie einen Blick auf Liquibase, jede Version erhält eine Datei, die auf die Änderungen verweist, die passieren müssen, dann können die Änderungsdateien mit einem aussagekräftigen String und nicht mit einer Nummer benannt werden.

2 - haben Sie einen zentralen Ort, um die nächste verfügbare Nummer zu bekommen, dann benutzen die Leute die letzte Nummer.

Ich habe Liquibase in der Vergangenheit ziemlich erfolgreich verwendet, und wir hatten nicht das Problem, das Sie beschreiben.

    
Angelo Genovese 23.07.2014 18:33
quelle
1

Wie Frederick Cheung vorgeschlagen , verwenden Sie Zeitstempel statt einer Seriennummer. Das Anwenden von Schemaänderungen in der Reihenfolge des Datumsstempels sollte funktionieren, da Schemaänderungen nur von Änderungen eines früheren Datums abhängen können.

Geben Sie außerdem den Namen des Entwicklers im Namen des alter-Skripts ein. Dies verhindert Mischkonflikte zu 100%.

Ihr Merge-Hook sollte nur nach neu hinzugefügten Alter-Scripts suchen (im zusammengeschlossenen Zweig vorhanden, aber nicht im Upstream-Zweig) und sie in der Reihenfolge des Zeitstempels ausführen.

    
Julian 26.07.2014 12:53
quelle
0

Ich habe zwei verschiedene Ansätze benutzt, um Ihr Problem in der Vergangenheit zu überwinden.

Das erste ist, ein ORM zu verwenden, das die Schemaaktualisierungen verarbeiten kann.

Der andere Ansatz besteht darin, ein Skript zu erstellen, das das Datenbankschema inkrementell erstellt. Wenn ein Entwickler eine zusätzliche Zeile in einer Tabelle benötigt, sollte er die entsprechende SQL-Anweisung hinzufügen, nachdem die Tabelle erstellt wurde. Ebenso, wenn er eine neue Tabelle benötigt, sollte er die SQL-Anweisung dafür hinzufügen. Dann wird die Verschmelzung zur Frage, ob die Dinge in der richtigen Reihenfolge ablaufen. Dies ist im Grunde der Vorgang der Datenbankaktualisierung in einem ORM. Solch ein Skript muss sehr defensiv codiert werden, und jede Aussage sollte prüfen, ob ihre Vorteile existieren.

    
jbr 22.07.2014 12:04
quelle
0

Für das dbvc-Befehlszeilentool verwende ich git log , um die Reihenfolge der Update-Skripte zu bestimmen.

%Vor%

In diesem Fall bestimmt die Reihenfolge der Commits die Reihenfolge, in der die Updates ausgeführt werden. Welches ist am wahrscheinlichsten, was Sie wollen.

  • Wenn Sie git merge b ausführen, werden die Aktualisierungen von Master zuerst und dann von B.
  • ausgeführt
  • Wenn Sie git rebase b ausführen, wird das Update von B zuerst und dann von Master ausgeführt.
Jasny - Arnold Daniels 02.08.2014 04:02
quelle

Tags und Links