【SQLServer】SchemaSpyでDB仕様書を効率良く作成【Docker】

こんにちは、サイオステクノロジーの佐藤 陽です。
今回は、実装済みのデータベースからER図などの仕様書を作成してくれる SchemaSpyというツールをご紹介します。

  • DBの仕様書を書くのが面倒…
  • せっかく作成したと思ったら、変更が入ってまた修正…
  • もう少し仕様書を効率的に作成・運用する方法無いの?

という人は是非最後までご覧ください。

はじめに

ER図を始めとして、DBの仕様書を作るのって大変ですよね。
テーブル内容が変わったりするたびに修正も加える必要がありますし、なかなか運用も大変です。

そんな時、このSchemaSpyを使う事で、仕様書をパパっと作成してくれます。

環境

今回は、Azure上に構築したSQLDatabaseを対象に仕様書の生成を行います。
ただし、使うドライバを切り替えれば様々なDBに対応出来るため、他のDBでも同様の手順で実行できるかと思います。

またSchemaSpyに関してはDockerで動かします。
Dockerの実行に関しては、WSL2のUbuntu20.04を利用します。

今回、Dockerの導入に関しては省略するため、各自でインストールの方を行ってください。

Install Docker Engine

準備

SchemaSpyのインストール方法や、構築方法は詳細にドキュメントにまとめられています。

こちらも合わせてご覧ください。

SchemaSpy

DockerImage

まずは、SchemaSpyのDockerイメージを取得します。

イメージはDockerHubにて公開されています、早速Pullしてきましょう。

ak-sato:/home/schemaspy$ sudo docker pull schemaspy/schemaspy

Using default tag: latest
latest: Pulling from schemaspy/schemaspy
5843afab3874: Pull complete
53c9466125e4: Pull complete
d8d715783b80: Pull complete
1539fff0f519: Pull complete
be45dfe6bf1c: Pull complete
e290a2b53a0c: Pull complete
437141805b4f: Pull complete
Digest: sha256:08290ff34c0fa4c1b28af555fbedf755159e42d02651a987e6077cb40a06f1ff
Status: Downloaded newer image for schemaspy/schemaspy:latest
docker.io/schemaspy/schemaspy:latest

ak-sato:/home/schemaspy$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
schemaspy/schemaspy latest a5201f7f8ceb 2 months ago 375MB

これでイメージを取得できました。

JDBCドライバ

次にSQLDatabaseへ接続するためのドライバを取得します。
SchemaSpyはJavaのアプリケーションであるため、SQLDatabaseへ接続するためにはJDBCドライバが必要になります。

MariaDBや、MySQL等は各種ドライバが含まれているようですが、SQLServerに関しては含まれていませんでした。
MicrosoftのページにJDBCドライバが用意されているのでこちらからダウンロードしてください。

Database

対象となるデータベースを作成します。
今回はAzure上にSQL Databaseを構築しました。

サンプルデータは以下のように作成します。
ER図を生成するという事で、ほどほどに外部キー参照を持つようにしました。

-- 1. 顧客テーブルの作成
create table dbo.customers (
    customer_id int primary key,
    first_name nvarchar(50),
    last_name nvarchar(50),
    email nvarchar(100)
);
-- 2. 注文テーブルの作成
create table dbo.orders (
    order_id int primary key,
    customer_id int,
    order_date date,
    total_amount decimal(10, 2),
    foreign key (customer_id) references customers(customer_id)
);
-- 3. 注文詳細テーブルの作成
create table dbo.order_details (
    order_detail_id int primary key,
    order_id int,
    product_name nvarchar(100),
    quantity int,
    price decimal(8, 2),
    foreign key (order_id) references orders(order_id)
);
-- 4. 顧客レコードの追加
insert into customers (customer_id, first_name, last_name, email)
values (1, 'John', 'Doe', 'john.doe@example.com'),
       (2, 'Jane', 'smith', 'jane.smith@example.com'),
       (3, 'David', 'johnson', 'david.johnson@example.com');

-- 5. 注文レコードの追加
insert into orders (order_id, customer_id, order_date, total_amount)
values (101, 1, '2023-09-20', 150.50),
       (102, 2, '2023-09-21', 220.75),
       (103, 3, '2023-09-22', 75.25);

-- 6. 注文詳細レコードの追加
insert into order_details (order_detail_id, order_id, product_name, quantity, price)
values (1001, 101, 'Product A', 2, 30.25),
       (1002, 101, 'Product B', 3, 25.50),
       (1003, 102, 'Product C', 1, 45.00);

設定ファイル

Databaseへの接続情報などを記載するために、Configurationを生成する必要があります。
今回は以下の内容で、ファイル名をschemaspy.propertiesとして保存しました。

  • schemaspy.tをmssqlとすると正しく動作しなかったので、mssql08としています。
  • schemaspy.dpの項目には、先ほどダウンロードしてきたjdbcドライバを指定します
  • Databaseへの接続にはSQLログインを利用するため、ユーザー名やパスワードなどを入力します
# type of database. Run with -dbhelp for details
# if mssql doesn't work: try mssql08 in combination with sqljdbc_7.2, this combination has been tested
schemaspy.t=mssql08
# optional path to alternative jdbc drivers.
schemaspy.dp=/drivers/mssql-jdbc-11.2.1.jre17.jar # JDBC Driver
# database properties: host, port number, name user, password
schemaspy.host={sql server name}
schemaspy.port=1433
schemaspy.db={database name}
schemaspy.u={db user name}
schemaspy.p={db user password}
# output dir to save generated files
schemaspy.o=/output
# db scheme for which generate diagrams
schemaspy.s=dbo

ディレクトリ構成

今回のディレクトリ構成は以下のようになっています。

── schemaspy
│   ├── drivers
│   │   └── mssql-jdbc-12.4.0.jre11.jar
│   ├── output
│   └── schemaspy.properties

実行

ファイルの準備ができたので実行します。

-v オプションでマウントし、docker runコマンドを実行します。

sudo docker run \
-v "/home/schemaspy/output:/output" \
-v "/home/schemaspy/schemaspy.properties:/schemaspy.properties" \
-v "/home/schemaspy/drivers:/drivers" \
schemaspy/schemaspy:latest

すると、

View the results by opening /output/index.html
INFO - Wrote table details in 0 seconds
INFO - Wrote relationship details of 3 tables/views to directory '/output' in 3 seconds.
INFO - View the results by opening /output/index.html

というメッセージが表示されました。
これで、/output/index.htmlを開くことで、ER図を確認することができます。

権限不足エラー

実行時、もしかしたら以下のようなエラーが出るかもしれません

ERROR - IOException
Unable to create directory /output/tables

この場合、出力先のoutputディレクトリに対する書き込み権限が無いため

chmod 777 output

などして、権限レベルを変更してください。

描画エラー

自分の環境だと、実行時に以下のようなエラーが乱発しました。

ERROR - dot -Tpng:cairo order_details.2degrees.dot -oorder_details.2degrees.png -Tcmapx: in label of node orders
.ERROR - dot -Tpng:cairo customers.1degree.dot -ocustomers.1degree.png -Tcmapx: Warning: cell size too small for content
ERROR - dot -Tpng:cairo customers.1degree.dot -ocustomers.1degree.png -Tcmapx: in label of node orders
ERROR - dot -Tpng:cairo customers.2degrees.dot -ocustomers.2degrees.png -Tcmapx: Warning: cell size too small for content

エラーメッセージを読む限り、おそらく描画周りのエラーなのですが、詳細不明です。

正しくアウトプットされていますし、ページを見ても描画が崩れている点は見えないため
一旦このエラーに関しては目をつむりたいと思います。

もし詳細分かる方居ましたら、記事へのコメントお願いします!

出力物の確認

早速、/output/index.htmlを開いてみます。

思ったよりもお洒落なページが生成されてます!
TOPページはTableに対する概要が記載されてますね。

Columnのタブも見てみます。

各Tableが持つColumnの情報が記載されています。
TypeやSize, Nullable情報も含まれていて、とても分かりやすいです。

次にRelationshipsのタブも見てみます。

まさにER図ですね。
最近はmermaidなどで簡単に書けるようになったとはいえ
1コマンド叩くだけで実装ベースのER図を生成してくれるのは非常に助かります。

妄想

今回は自分でDockerコマンド叩いて出力しましたが、出来ればここを自動化したいですよね。

  1. 自動で定期的にDockerコマンドを実行
  2. 出力されたものを自動でホスティング先へデプロイ

なんて出来たら、常に最新の仕様書が閲覧できる環境が作れそうです。

素敵。

また試してみたらブログ化してみたいと思います。

→書きました。

【SchemaSpy】データベース仕様書の作成と公開を自動化してみた【Azure Pipelines】

まとめ

今回は、SchemaSpyというツールを使って、実際のDBをベースに仕様書を作成してみました。
仕様書を作ったり運用する作業ってなかなかモチベーションが上がらないので、こういった便利ツールを使って自動化していきたいですね。

ではまた!

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です