こんにちは、サイオステクノロジーの佐藤 陽です。
今回は、実装済みのデータベースからER図などの仕様書を作成してくれる SchemaSpyというツールをご紹介します。
- DBの仕様書を書くのが面倒…
- せっかく作成したと思ったら、変更が入ってまた修正…
- もう少し仕様書を効率的に作成・運用する方法無いの?
という人は是非最後までご覧ください。
はじめに
ER図を始めとして、DBの仕様書を作るのって大変ですよね。
テーブル内容が変わったりするたびに修正も加える必要がありますし、なかなか運用も大変です。
そんな時、このSchemaSpyを使う事で、仕様書をパパっと作成してくれます。
環境
今回は、Azure上に構築したSQLDatabaseを対象に仕様書の生成を行います。
ただし、使うドライバを切り替えれば様々なDBに対応出来るため、他のDBでも同様の手順で実行できるかと思います。
またSchemaSpyに関してはDockerで動かします。
Dockerの実行に関しては、WSL2のUbuntu20.04を利用します。
今回、Dockerの導入に関しては省略するため、各自でインストールの方を行ってください。
準備
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コマンド叩いて出力しましたが、出来ればここを自動化したいですよね。
- 自動で定期的にDockerコマンドを実行
- 出力されたものを自動でホスティング先へデプロイ
なんて出来たら、常に最新の仕様書が閲覧できる環境が作れそうです。
素敵。
また試してみたらブログ化してみたいと思います。
→書きました。
まとめ
今回は、SchemaSpyというツールを使って、実際のDBをベースに仕様書を作成してみました。
仕様書を作ったり運用する作業ってなかなかモチベーションが上がらないので、こういった便利ツールを使って自動化していきたいですね。
ではまた!