😎

PostgreSQLでローカルでストアード・プロシージャーを自動適用する

2024/12/09に公開

目的

ユニークビジョン株式会社 Advent Calendar 2024のシリーズ2、12/2の記事です。

dockerなどでローカルにPostgreSQLが動いているとします。ストアード・プロシージャーを開発している時は修正するたびにPostgreSQLに適用したいです。

ファイルをセーブするたびに自動で適用されると開発が楽になるのでやってみます。

説明

docker-compose

dockerでPostgreSQLを立ち上げます。これでlocalhost:5432でアクセスできます。

docker-compose.yaml
services:
  postgresql:
    image: postgres:17.0
    environment:
      - POSTGRES_DB=web
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    ports:
      - 5432:5432
    volumes:
      - samples_postgresql_data:/var/lib/postgresql/data

volumes:
  samples_postgresql_data:

ディレクトリ構成

sample1.sqlやsample2.sqlが更新されると自動適用したいです。

- db
  - bin
    - apply_procedure_local.sh
    - watch.sh
  - sql
    - stored
      - sample1.sql
      - sample2.sql

DB適用

自動適用をするための、適用のスクリプトを用意します。
stored以下にあるsqlをすべて適用しています。

apply_procedure_local.sh
#!/bin/sh
SCRIPT_DIR=$(cd $(dirname $0); pwd)
SQL_DIR=$SCRIPT_DIR/../sql

cat $SQL_DIR/stored/*.sql > ./all.sql

PGPASSWORD=pass psql --set "ON_ERROR_STOP=1" -p ${PGPORT:-5432} -h ${PGHOST:-localhost} -U ${PGUSER:-user} ${PGDATABASE:-web} -f ./all.sql

rm ./all.sql

自動適用

entrというコマンドを利用します。これはファイルが変更されると任意のコマンドを実行してくれます。Ubuntuならaptでインストールできます。

sqlファイルが変更されたら、apply_procedure_local.shを呼び出します。

watch.sh
#!/bin/sh
SCRIPT_DIR=$(cd $(dirname $0); pwd)
DB_DIR=$SCRIPT_DIR/..

if ! command -v entr > /dev/null; then
    echo "entr がインストールされていません。インストールしてください"
    return 1
fi
find $DB_DIR/sql/stored/ -name '*.sql' | entr "$DB_DIR/bin/apply_procedure_local.sh"

あとはwatch.shを起動しておくだけでOKです。

まとめ

RustとPostgreSQLでストアード・プロシージャーのTDDで紹介したTDDをやってる時に自動適用は便利です。

Discussion