SchmaSpyで手元のPostgreSQL用DDLからテーブル定義書を生成してみる

方法

PostgreSQLのDockerでDDLからテーブルを構築し、起動完了までwaitしてからSchemaSpyを別コンテナで実行する
db立ち上げからSchemaSpy実行までdocker-composeで完結するよう環境依存をできるだけ減らしてみた。

tree
├── docker-compose.yml
├── output
├── postgres
│   ├── Dockerfile
│   └── docker-entrypoint-initdb.d
│       ├── 01.create-db.sql
│       ├── 02.create-role.sql
│       ├── 03.create-schema.sql
│       ├── 04.create-tables.sql
│       └── 99.shutdown.sh
└── schemaspy
    └── schemaspy.properties
docker-compose.yml
version: '3'
services:
  db:
    build: ./postgres
    ports:
      - 5432:5432
    volumes:
      - "${PWD}/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d"
    networks:
      - backend
    environment:
      POSTGRES_PASSWORD: postgres
      WAIT_FOR_SCHEMASPY: 30 # schemaspyで生成終了するまでDBを停止させない
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      start_period: "5s" # ヘルスチェックの開始遅延
      retries: 3
      timeout: "5s"
      interval: "5s" 
  schemaspy:
    image: schemaspy/schemaspy:6.1.0
    volumes:
      - "${PWD}/schemaspy/schemaspy.properties:/schemaspy.properties"
      - "${PWD}/output:/output"
    networks:
      - backend
    depends_on:
      db:
        condition: service_healthy
networks:
  backend:
postgres/Dockerfile
# FROM postgres:14.5-bullseye
FROM postgres:11.17-bullseye
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.UTF-8

pg_ctlで指定時間秒数後にdbをシャットダウンするよう指定している。

postgres/docker-entrypoint-initdb.d/99.shutdown.sh
#!/bin/bash

nohup bash -c "sleep ${WAIT_FOR_SCHEMASPY}; pg_ctl stop -D ${PGDATA};" &
schemaspy/schemaspy.properties
# type of database. Run with -dbhelp for details
schemaspy.t=pgsql11
# optional path to alternative jdbc drivers.
schemaspy.dp=/work/postgresql-42.5.0.jar
# database properties: host, port number, name user, password
schemaspy.host=db
schemaspy.port=5432
schemaspy.db=postgres
schemaspy.u=postgres
schemaspy.p=postgres
# output dir to save generated files
# schemaspy.o=path/to/output
# db scheme for which generate diagrams
schemaspy.s=appuser

実行

以下のコマンドを実行

  • docker-compose up

クリーン

以下のコマンドを実行

  • docker-compose down

TODO

  • 日本語化対応

注意

以下のエラーが発生した場合はデータベースタイプが合っていないかもしれない。 PostgreSQL11の場合はデータベースタイプ pgsql11 を指定する。

console
schemaspy_1  | Gathering schema details......WARN  - Failed to retrieve stored procedure/function details using sql 'select r.routine_name, case when p.proisagg then 'AGGREGATE' else 'FUNCTION' end as routine_type, case when p.proretset then 'SETOF ' else '' end || case when r.data_type = 'USER-DEFINED' then r.type_udt_name else r.data_type end as dtd_identifier, r.external_language as routine_body, r.routine_definition, r.sql_data_access, r.security_type, r.is_deterministic, d.description as routine_comment from information_schema.routines r left join pg_namespace ns on r.routine_schema = ns.nspname left join pg_proc p on ns.oid = p.pronamespace and r.routine_name = p.proname left join pg_description d on d.objoid = p.oid where r.routine_schema = :schema'
schemaspy_1  | ERROR: ?p.proisagg???????
schemaspy_1  |   Hint: ?"p.prolang"????????????????
schemaspy_1  |   Position: 34
schemaspy_1  | (0sec)
schemaspy_1  | Connecting relationships......(0sec)