paint-brush
Git-Hooks mit MySQL verwendenvon@yuridanilov
4,711 Lesungen
4,711 Lesungen

Git-Hooks mit MySQL verwenden

von Yuri Danilov7m2023/09/30
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Test-DB erstellen Erstellen Sie nach dem Empfang einen Git-Hook Führen Sie SQL-Skripte per Push aus

People Mentioned

Mention Thumbnail
featured image - Git-Hooks mit MySQL verwenden
Yuri Danilov HackerNoon profile picture
0-item
1-item

Versionskontrollsysteme und insbesondere Git sind wichtige Tools zum Verfolgen von Codeänderungen, zur Zusammenarbeit mit Ihrem Team und zur Gewährleistung der Stabilität Ihrer Codebasis. Während Git in erster Linie für Quellcode konzipiert ist, können Sie es auch in Kombination mit MySQL- Datenbanken zur Versionskontrolle und Schema-Änderungsverwaltung verwenden.


In diesem Artikel untersuchen wir anhand spezifischer Beispiele in einem Leitfadenformat, wie man Git mit MySQL zur Versionskontrolle mithilfe von Git-Hooks integriert. Alle in den Auflistungen aufgeführten Skripte sind voll funktionsfähig und vollständig. Sie können sie sequentiell in Ihrer Testumgebung reproduzieren.


Erstellen wir zunächst eine Testdatenbank und einen Benutzer:

 create database testdb_remote; create user 'user_remote'@'localhost' identified WITH mysql_native_password by 'remote123'; grant all on testdb_remote.* to 'user_remote'@'localhost'; 


Erstellen einer Testdatenbank


Als nächstes erstellen wir ein Remote-Repository. Dies kann ein Repository auf einem beliebigen Remote-Server sein, der Einfachheit halber erstellen wir es jedoch lokal. Um die Ausführung von Befehlen zu vereinfachen, verwende ich Git Bash. Mein lokaler Computer verfügt bereits über einen Git-Ordner, also verwende ich ihn:

 cd /c/git mkdir testdb.remote cd testdb.remote git init --bare 


Erstellen eines Remote-Repositorys

Und erstellen Sie ein lokales Repository als Klon des Remote-Repositorys:

 cd /c/git git clone /c/git/testdb.remote testdb.local cd testdb.local git ls-files 


Erstellen eines lokalen Repos


Es sind keine Dateien im Repository vorhanden; Lassen Sie uns eines erstellen und unsere Änderungen in das Remote-Repository übertragen:

 echo "Test DB repo" > readme.md git status git add . git commit -m "1st commit" git push 


Erster Stoß


Lassen Sie uns den Inhalt des Remote-Repositorys überprüfen:

 cd /c/git/testdb.remote git ls-tree --full-tree -r HEAD 


Datei im Remote-Repository


Im Remote-Repository gibt es einen Hooks-Ordner, der mehrere Dateien mit Beispielen enthält:

 ls -1 /c/git/testdb.remote/hooks 


Musterhaken


Hooks sind Skripte, die ausgeführt werden, wenn bestimmte Ereignisse eintreten. Git verfügt über clientseitige und serverseitige Hooks. Clientseitige Hooks werden durch Vorgänge wie Festschreiben und Zusammenführen ausgelöst. Serverseitige Hooks werden bei Netzwerkvorgängen wie dem Empfang von Push-Commits ausgeführt. Haken werden hier ausführlich beschrieben. Für die Umsetzung der Logik gibt es verschiedene Möglichkeiten; Ich gebe ein Beispiel für die Verwendung des serverseitigen Post-Receive -Hooks.


Im Hooks-Ordner müssen wir eine Datei mit dem Namen „post-receive“ erstellen. Dies ist ein normales Bash-Skript:

 #!/bin/sh while read oval nval ref do echo List of files changed in the commit: git diff --name-only $oval $nval done


Das obige Skript wird auf dem Server ausgeführt, wenn ein Push erfolgreich abgeschlossen wurde, und gibt eine Liste der geänderten Dateien aus. Lassen Sie uns überprüfen, wie es funktioniert, indem wir eine Zeile zur readme.md hinzufügen und die Änderungen an das Remote-Repository übertragen:

 cd /c/git/testdb.local echo "New line" >> readme.md git add . git commit -m "Line added" git push 


Testen des Post-Receive-Hook-Skripts


Sie können sehen, dass beim Ausführen des Befehls „git push“ die Ausgabe jetzt Zeilen enthält, die mit remote: – Dies ist die Ausgabe des Post-Receive-Skripts, das auf dem Server ausgeführt wurde.

Apropos grundlegende Änderungen: Dateien können hinzugefügt, geändert und gelöscht werden. Sie können verschiedene Ansätze verfolgen, um diese Änderungen auf die Datenbank anzuwenden:


  1. Nehmen Sie Änderungen an der Datenbank nur vor, wenn Sie neue Dateien hinzufügen. In diesem Fall können Sie alle Änderungen für eine bestimmte Aufgabe in einer einzigen Datei speichern. Diese Datei kann den Namen der Aufgabe aus dem Bug-Tracking-System enthalten. Dies ist während der Entwicklung möglicherweise nicht sehr praktisch, aber solche Änderungen sind einfacher zu handhaben.
  2. Behalten Sie für jedes Objekt (Tabellen, Prozeduren) eine separate Datei im Repository und übernehmen Sie Änderungen in der Datenbank, wenn Sie Dateien ändern oder hinzufügen.
  3. Ein umfassenderer Ansatz besteht darin, für jede Aufgabe (Änderungsanforderung) einen separaten Ordner zu erstellen und darin die Dateien abzulegen, die im Rahmen der Installation einer bestimmten Version ausgeführt werden sollen. Erstellen Sie gleichzeitig eine zusätzliche Datei, die die Liste der Dateien und die Reihenfolge beschreibt, in der sie installiert werden sollen. Dieser Ansatz ist flexibler, aber gleichzeitig komplexer sowohl für die Entwicklung als auch für die Pipeline-Implementierung.


Angenommen, Sie haben die zweite Option gewählt, sodass Sie hinzugefügte oder geänderte Dateien ausführen müssen. Wir können solche Dateien wie hier beschrieben filtern, indem wir den Parameter --diff-filter=AM hinzufügen:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval done


Fügen Sie ein paar Dateien hinzu und ändern Sie auch die Datei readme.md erneut:

 echo "SELECT 1;" > test1.sql echo "SELECT 2;" > test2.sql echo "SELECT 3;" > test3.sql echo "New line 2" >> readme.md git add . git commit -m "New files" git push


Die Ausgabe des Hook-Skripts enthält 4 Dateien:

Liste aller geänderten Dateien


Wir bearbeiten die Dateien test1.sql und readme.md, löschen test2.sql und fügen eine weitere Datei hinzu:

 echo "SELECT 11;" > test1.sql echo "New line 2" >> readme.md rm test2.sql echo "SELECT 4;" > test4.sql git add . git commit -m "Modify, remove and add" git push


Es werden nur geänderte und hinzugefügte Dateien angezeigt:

Nur hinzugefügte oder geänderte Dateien


Unser Ziel ist es, nach jedem erfolgreichen Push SQL-Skripte auszuführen, daher müssen wir nur Dateien dieses Typs filtern; In unserem Fall legen wir die Anforderung fest, dass sie alle die Erweiterung „.sql“ haben müssen. Fügen Sie zum Filtern den Parameter -- "*.sql" zum Befehl git diff hinzu:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" done


Um Skripte auszuführen, müssen wir auch eine Verbindung zur Datenbank herstellen können. Dazu erstellen wir Zugangsdaten und testen die Verbindung:

 mysql_config_editor set --login-path=testdb_remote --host=localhost --port=3306 --user=user_remote --password mysql --login-path=testdb_remote --database=testdb_remote 


Creds für MySQL erstellen


Ändern Sie unser Skript, um die „.sql“-Dateien zu durchlaufen, jede Datei auszuführen und das Ergebnis zu überprüfen. Wir müssen auch die Listenausgabe sortieren, um die Dateien in der erforderlichen Reihenfolge auszuführen. Mit dem Befehl git show zeigen wir den Inhalt des SQL-Skripts an und leiten es zur Ausführung durch MySQL durch die Pipe .

Die Variable „$?“ enthält 0, wenn das SQL-Skript erfolgreich ausgeführt wurde, und einen anderen Wert, wenn ein Fehler aufgetreten ist:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: for file in $(git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" | sort); do git show master:${file} | mysql --login-path=testdb_remote --database=testdb_remote echo "FILE: ${file} - result $?" done done


Führen Sie einen weiteren Test durch – löschen Sie alle zuvor erstellten „.sql“-Dateien und erstellen Sie Skripte für:


  • Tabellenerstellung
  • Einfügen von Daten in die Tabelle
  • Erstellen einer Prozedur zum Empfangen von Daten aus der Tabelle
  • Skript mit einem Fehler


Außerdem müssen wir jedem Dateinamen ein Präfix (1_, 2_ usw.) hinzufügen, um die gewünschte Ausführungsreihenfolge der Dateien sicherzustellen:

 rm *.sql echo "DB Initialization" >> readme.md echo " DROP TABLE IF EXISTS customers; CREATE TABLE customers ( id int UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(255) DEFAULT NULL, PRIMARY KEY (id) ); " > 1_customers.sql echo " INSERT INTO customers (id, name) VALUES (1, 'John Doe'), (2, 'Jane Smith') AS new ON DUPLICATE KEY UPDATE customers.name = new.name; " > 2_customers_init.sql echo " DROP PROCEDURE IF EXISTS get_customer; DELIMITER $$ CREATE PROCEDURE get_customer(IN customer_id int UNSIGNED) BEGIN SELECT c.id, c.name FROM customers c WHERE c.id = customer_id; END $$ " > 3_get_customer.sql echo "SELECT FROM customers;" > 4_error_select.sql ls -1


Wir haben also vier „.sql“-Dateien, die ausgeführt werden müssen:

Liste der Dateien

Wir nehmen Änderungen am Repository vor:

Es werden nur SQL-Dateien ausgeführt


Und wir sehen, dass beim Ausführen git push die Dateien nacheinander ausgeführt werden und das Ausführungsergebnis (MySQL-Befehls-Exit-Code) jeder Datei angezeigt wird. Die Datei „4_error_select.sql“ enthält einen Syntaxfehler, daher ist das Ergebnis ihrer Ausführung 1.


Und zum Schluss überprüfen wir, was wir in der Datenbank haben:

 mysql --login-path=testdb_remote --database=testdb_remote show tables; call get_customer(1); call get_customer(2); 


Testen von in der Datenbank erstellten Objekten


Wie Sie sehen, wurden die Tabelle und die Prozedur in der Remote-Datenbank erstellt. Die Prozedur wird erfolgreich ausgeführt und gibt Daten zurück.


Um die Lesbarkeit der Hook-Skript-Ausgabe zu verbessern, können Sie die MySQL-CLI-Ausgabe unterdrücken oder in eine Protokolldatei umleiten. Sie können auch das Ergebnis der MySQL-Befehlsausführung analysieren und dem Hook-Skript weitere Logik hinzufügen.


Sie können beispielsweise SQL-Skripte auf einer Testdatenbank ausführen und dann einige Tests darauf ausführen (wie ich hier beschrieben habe). Wenn die Tests in der Testdatenbank erfolgreich abgeschlossen wurden, führen Sie SQL-Skripte in der Produktionsdatenbank aus und führen Sie wahrscheinlich auch einige Tests darin aus.

Durch die Analyse der Ergebnisse jedes Schritts können Sie Pipelines beliebiger Konfiguration erstellen.


Natürlich hat jeder Ansatz eine Reihe von Vorteilen und Einschränkungen. Beim zweiten Ansatz ist es notwendig, die Reihenfolge sicherzustellen, in der die Skripte ausgeführt werden, da wir beispielsweise keine Daten in eine Tabelle einfügen können, bevor diese erstellt wurde. Es muss außerdem sichergestellt werden, dass Sie Skripte erneut ausführen können, d. h. Situationen korrekt behandeln können, in denen sich das zu erstellende Objekt bereits in der Datenbank befindet oder die Datenbank bereits die hinzuzufügenden Daten enthält.


Bei Verwendung eines Versionierungssystems wird der Entwicklungsprozess etwas komplizierter, da Änderungen in Skripten eines vorgegebenen Formats zusätzlich formalisiert werden müssen. Durch die Verwendung einer Installationsdatei können Sie jedoch eine gewisse Flexibilität erreichen.


Der Hauptvorteil der beschriebenen Technik ist die Implementierung der Versionierung in der Datenbank mit sehr geringem Aufwand sowie die Möglichkeit , CI/CD-Pipelines zu implementieren.

Um zu beurteilen, ob dies für Sie nützlich sein könnte, können Sie sich zunächst fragen: Wie oft schreiben Sie Code direkt in der Produktion?