🕵️

SchemaSpyを駆使してDB仕様書を自動生成しよう

2023/10/10に公開

はじめに

ソフトウェア開発の日常では、データベース設計やデータベース変更管理は不可欠なタスクです。しかし、開発初期にExcelで管理していたけど今は誰にも参照されていない遺物が誕生してしまうこともあるかと、、

そうなってしまう背景として、以下のような課題があることが考えられます。

  • データベース構造の複雑さ
    • プロジェクトが成長するにつれて構造が複雑化する
  • ドキュメンテーションの手間
    • 手作業での仕様書作成・更新は時間も気力も使う
  • チーム間のコミュニケーション不足
    • 変更に関する情報がうまく連携できていない

これらの課題に対処するためにSchemaSpyというツールを活用します。SchemaSpyは既存のデータベースからドキュメントをHTML形式で自動生成してくれます。
個人開発でも活用中なので備忘録も兼ねてセットアップから利用方法まで解説していきます。

環境

環境はDockerで作成します。

  • Docker: 24.0.6
  • PC: macOS Ventura 13.5
    • チップ: Apple M2
  • SchemaSpy: 6.2.4
  • PostgreSQL: 15.4

手元で動作確認したい方は以下のリポジトリを活用ください

https://github.com/takumi-pro/schemaspy-sample

ディレクトリ構造

/schemaspy-sample
├── Makefile
├── README.md
├── postgres-data
├── output        # schemaspy自動生成ファイル
├── docker
│   └── schemaspy
│       └── Dockerfile
├── docker-compose-spy.yml
├── docker-compose.yml
├── drivers
│   └── postgresql-42.6.0.jar
├── init.sql
└── schemaspy.properties

SchemaSpyのセットアップ

コンテナの定義

今回は以下の3つのコンテナを作成します。

  • DB: PostgreSQL
  • SchemaSpy
  • Webサーバ: nginx

docker-compose.ymlにDBコンテナ、docker-compose-spy.ymlにSchemaSpyとWebサーバコンテナを定義します。

docker-compose.yml
version: '3.8'
services:
  db:
    image: postgres:15.4
    container_name: postgres
    environment:
      POSTGRES_DB: blog
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
    ports:
      - "5432:5432"
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - schemaspy-sample

networks:
  schemaspy-sample:
    external: true
docker-compose-spy.yml
version: '3.8'
services:
  spy:
    build:
      context: .
      dockerfile: ./docker/schemaspy/Dockerfile
    image: schemaspy/schemaspy
    container_name: spy
    tty: true
    volumes:
      - ./output:/output
      - ./schemaspy.properties:/schemaspy.properties
      - ./drivers/postgresql-42.6.0.jar:/drivers/postgresql.jar
    command: "java -jar schemaspy.jar"
    networks:
      - schemaspy-sample

  nginx_schemaspy:
    image: nginx
    container_name: "nginx_schemaspy"
    depends_on:
      - spy
    ports:
      - "8080:80"
    volumes:
      - ./output:/usr/share/nginx/html
    networks:
      - schemaspy-sample

networks:
  schemaspy-sample:
    external: true

Dockerfileの定義

SchemaSpy用のDockerfileを作成します。
wget -O schemaspy.jar ${APP_URL}の部分で実行ファイルをダウンロードし、schemaspy.jarとしてコンテナ内に保存しています。このファイルを実行することで、指定したディレクトリ(SchemaSpy設定ファイルの作成で設定)にDB仕様書が出力されます。

FROM openjdk:8u212-jdk-alpine

ENV APP_URL https://github.com/schemaspy/schemaspy/releases/download/v6.1.0/schemaspy-6.1.0.jar

WORKDIR /

RUN apk --update add graphviz ttf-dejavu && \
    apk --update add --virtual .builddep tzdata wget libressl && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    wget -O schemaspy.jar ${APP_URL} && \
    apk del .builddep && \
    rm -rf /var/cache/apk/*

SchemaSpy設定ファイルの作成

schemaspy.propertiesというファイルで、DBのホスト名やユーザ名、仕様書を出力するディレクトリを指定することができます。

https://schemaspy.readthedocs.io/en/latest/started.html#configuration

schemaspy.properties
# type of database. Run with -dbhelp for details
schemaspy.t=pgsql
# optional path to alternative jdbc drivers.
schemaspy.dp=/drivers/postgresql.jar
# database properties: host, port number, name user, password
schemaspy.host=db
schemaspy.port=5432
schemaspy.db=blog
schemaspy.u=root
schemaspy.p=root
# output dir to save generated files
schemaspy.o=./output
# db scheme for which generate diagrams
schemaspy.schemas=public

SQLの用意

今回はblogアプリケーションを想定して以下のようなSQLとしました。

init.sql
CREATE TABLE "users" (
  "id" uuid PRIMARY KEY,
  "name" VARCHAR(255) NOT NULL,
  "email" VARCHAR(255) NOT NULL,
  "password" VARCHAR(255) NOT NULL,
  "created_at" TIMESTAMP,
  "updated_at" TIMESTAMP
);

CREATE TABLE "articles" (
  "id" uuid PRIMARY KEY,
  "title" VARCHAR(255) NOT NULL,
  "body" TEXT,
  "user_id" uuid REFERENCES users(id),
  "created_at" TIMESTAMP,
  "updated_at" TIMESTAMP
);

CREATE TABLE "comments" (
  "id" uuid PRIMARY KEY,
  "article_id" uuid REFERENCES articles(id),
  "user_id" uuid REFERENCES users(id),
  "body" TEXT,
  "created_at" TIMESTAMP,
  "updated_at" TIMESTAMP
);

PostgreSQLドライバーの配置

docker-compose-spy.ymlのvolumesでドライバーを指定しているのでダウンロードして/driversに配置します。以下からダウンロードしました。

https://jdbc.postgresql.org/download/

SchemaSpyの実行

セットアップが完了したのでSchemaSpyを実行していきます。
まずはDBコンテナを起動します。

docker compose up -d

続いてSchemaSpyコンテナを起動します。

docker compose -f docker-compose-spy.yml up --build --force-recreate spy
docker rm spy
docker compose -f docker-compose-spy.yml up -d --build nginx_schemaspy

SchemaSpyコンテナを実行し仕様書を出力してもらったらnginxでホスティングしています。
これでhttp://localhost:8080にアクセスすると以下のような画面が表示されているはずです。

仕様書の確認

先ほどの画面でスキーマを選択するとテーブル一覧画面に遷移します。

テーブル詳細には、型・制約(外部キー、NULL、主キー)などが記載されています。

テーブルのリレーションも図にしてわかりやすく表示してくれていますね。

まとめ

SchemaSpyを活用してDB仕様書を自動生成してみました。これでドキュメントが腐ることはなくなりました。個人開発だけでなく実務でもドキュメント作成に積極的に活用していきたいと思います。

参考

https://schemaspy.readthedocs.io/en/v6.2.0/started.html

https://gmor-sys.com/2022/10/19/db-document-autocreation-tool/

https://zenn.dev/onozaty/articles/schema-spy-er

GitHubで編集を提案

Discussion