paint-brush
MySQL での Git フックの使用@yuridanilov
4,692 測定値
4,692 測定値

MySQL での Git フックの使用

Yuri Danilov7m2023/09/30
Read on Terminal Reader

長すぎる; 読むには

テストDBの作成 受信後に git フックを作成する プッシュ時にSQLスクリプトを実行する
featured image - MySQL での Git フックの使用
Yuri Danilov HackerNoon profile picture
0-item
1-item

バージョン管理システム、特に Git は、コードの変更を追跡し、チームと共同作業し、コードベースの安定性を確保するために不可欠なツールです。 Git は主にソース コード用に設計されていますが、バージョン管理やスキーマ変更管理のためにMySQLデータベースと組み合わせて使用することもできます。


この記事では、Git フックを使用してバージョン管理のために Git を MySQL と統合する方法を、ガイド形式の具体的な例とともに説明します。リストにあるすべてのスクリプトは完全に機能し、完全です。テスト環境で順番に再現できます。


まず、テスト データベースとユーザーを作成しましょう。

 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'; 


テストデータベースの作成


次に、リモートリポジトリを作成します。これは任意のリモート サーバー上のリポジトリにすることができますが、簡単にするためにローカルに作成します。コマンドを実行するのに便利なように、git bash を使用します。私のローカルマシンにはすでに git フォルダーがあるので、それを使用します。

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


リモートリポジトリの作成

そして、リモート リポジトリのクローンとしてローカル リポジトリを作成します。

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


ローカル リポジトリの作成


リポジトリにはファイルがありません。作成して、変更をリモート リポジトリにプッシュしましょう。

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


最初の一押し


リモート リポジトリの内容を確認してみましょう。

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


リモート リポジトリ内のファイル


リモート リポジトリにはフック フォルダーがあり、サンプルを含むいくつかのファイルが含まれています。

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


サンプルフック


フックは、特定のイベントが発生したときに実行されるスクリプトです。 Git にはクライアント側とサーバー側のフックがあります。クライアント側のフックは、コミットやマージなどの操作によってトリガーされます。サーバー側のフックは、プッシュされたコミットの受信などのネットワーク操作で実行されます。フックについては、ここで詳しく説明されています。ロジックを実装するにはさまざまなオプションがあります。 post-receiveサーバー側フックの使用例を示します。


フック フォルダー内に、「post-receive」という名前のファイルを作成する必要があります。これは通常の bash スクリプトです。

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


上記のスクリプトは、プッシュが正常に完了するたびにサーバー上で実行され、変更されたファイルのリストを出力します。 readme.md に行を追加し、変更をリモート リポジトリにプッシュして、どのように機能するかを確認してみましょう。

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


受信後フックスクリプトのテスト


git Push コマンドを実行すると、出力には、 remote: - これは、サーバー上で実行された受信後スクリプトの出力です。

基本的な変更といえば、ファイルの追加、変更、削除が可能です。これらの変更をデータベースに適用する方法には、さまざまな方法があります。


  1. 新しいファイルを追加する場合にのみ、データベースに変更を加えてください。この場合、特定のタスクに対するすべての変更を 1 つのファイルに保存できます。このファイルには、バグ追跡システムからのタスクの名前が含まれる場合があります。これは開発中はあまり便利ではないかもしれませんが、そのような変更は扱いやすくなります。
  2. リポジトリ内にオブジェクト (テーブル、プロシージャ) ごとに個別のファイルを保持し、ファイルを変更または追加するときにデータベースに変更を適用します。
  3. より包括的なアプローチは、タスク (変更リクエスト) ごとに個別のフォルダーを作成し、その中に特定のリリースのインストールの一部として実行するファイルを配置することです。同時に、ファイルのリストとそれらをインストールする順序を記述した追加ファイルを作成します。このアプローチはより柔軟ですが、同時に開発とパイプライン実装の両方においてより複雑になります。


2 番目のオプションを選択したと仮定すると、追加または変更されたファイルを実行する必要があります。ここで説明するように、パラメータ--diff-filter=AMを追加することで、そのようなファイルをフィルタリングできます。

 #!/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


いくつかのファイルを追加し、readme.md も再度変更します。

 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


フック スクリプトの出力には 4 つのファイルが含まれます。

変更されたすべてのファイルのリスト


test1.sql ファイルと readme.md ファイルを編集し、test2.sql を削除して、別のファイルを追加します。

 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


変更および追加されたファイルのみが表示されます。

追加または変更されたファイルのみ


私たちの目標は、プッシュが成功するたびに SQL スクリプトを実行することなので、このタイプのファイルのみをフィルタリングする必要があります。この例では、すべてに「.sql」拡張子が必要であるという要件を設定します。フィルターするには、パラメーター-- "*.sql"git diffコマンドに追加します。

 #!/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


スクリプトを実行するには、データベースに接続できる必要もあります。このために、認証情報を作成し、接続をテストします。

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


MySQL の認証情報の作成


「.sql」ファイルを反復処理し、各ファイルを実行して結果を確認するようにスクリプトを変更します。また、必要な順序でファイルを実行するには、リスト出力をソートする必要があります。 git show コマンドを使用して、SQL スクリプトの内容を表示し、それをパイプ経由で渡して MySQL で実行します

変数「$?」 SQL スクリプトが正常に実行された場合は 0 が含まれ、エラーがあった場合は別の値が含まれます。

 #!/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


もう一度テストを実行します。以前に作成した「.sql」ファイルをすべて削除し、次のスクリプトを作成します。


  • テーブルの作成
  • テーブルにデータを挿入する
  • テーブルからデータを受信するプロシージャを作成する
  • エラーを含むスクリプト


また、ファイルが適切な実行順序になるように、各ファイル名にプレフィックス (1_、2_ など) を追加する必要があります。

 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


したがって、実行する必要がある「.sql」ファイルが 4 つあります。

ファイルのリスト

リポジトリに変更を加えます。

SQLファイルのみが実行されます


そして、 git pushを実行すると、ファイルが順次実行され、各ファイルの実行結果(MySQLコマンドの終了コード)が表示されることがわかります。ファイル「4_error_select.sql」には構文エラーが含まれているため、実行結果は 1 になります。


最後に、データベースにあるものを確認してみましょう。

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


DBで作成したオブジェクトのテスト


ご覧のとおり、テーブルとプロシージャはリモート データベースに作成されました。プロシージャは正常に実行され、データが返されます。


フック スクリプトの出力を読みやすくするには、MySQL CLI 出力を抑制するか、ログ ファイルにリダイレクトします。 MySQL コマンドの実行結果を分析し、フック スクリプトにロジックを追加することもできます。


たとえば、テスト データベースで SQL スクリプトを実行し、そのデータベースでいくつかのテストを実行できます (ここで説明したように)。テスト データベースでテストが正常に完了した場合は、実稼働データベースで SQL スクリプトを実行し、おそらく実稼働データベースでもいくつかのテストを実行します。

各ステップの結果を分析することで、任意の構成のパイプラインを作成できます。


もちろん、それぞれのアプローチには多くの利点と制限があります。 2 番目のアプローチでは、たとえばテーブルが作成されるまでテーブルにデータを挿入できないため、スクリプトの実行順序を保証する必要があります。また、スクリプトを再実行できること、つまり、作成中のオブジェクトがすでにデータベースに存在する場合、またはデータベースに追加するデータがすでに含まれている場合の状況を正しく処理できることを確認することも必要です。


バージョン管理システムを使用する場合、所定の形式のスクリプトの変更をさらに形式化する必要があるため、開発プロセスは少し複雑になります。ただし、インストール ファイルを使用すると、ある程度の柔軟性を実現できます。


ここで説明した手法の主な利点は、ほとんど労力をかけずにデータベースでのバージョン管理を実装できることと、 CI/CD パイプラインを実装できることです。

これが役立つかどうかを評価するには、次のことを自問することから始めます。実稼働環境でコードを直接記述する頻度はどれくらいですか?