dbterdを使ったER図の作成

2024/03/20に公開

dbtを使ってデータモデルを構築していると、たま〜にER図欲しいな~って思っちゃう!
ってことで、今回はdbterdを使って、ER図を作成してみます!
作成するパターンとしては次のとおりです。

  • dbterdでDBMLを作成し、dbml-rendererでDBMLをSVGとして画像形式のER図を生成する
  • dbterdでmermaid形式のER図を生成する

検証環境

今回はUbuntu20.04のコンテナ上に必要なパッケージをインストールして検証しました。
dbtの接続先のウェアハウスはduckdbを使っています。
各種パッケージのバージョン

  • Python=3.11
  • dbterd=1.12.0
  • dbml-renderer=1.0.27

dbterdとは

https://github.com/datnguye/dbterd
dbtアーティファクトファイルからDBML、Mermaid、PlantUML、GraphViz、D2を生成するCLIツールです。
必要なdbtのアーティファクトファイルはmanifest.json、catalog.jsonです。

dbml-rendererとは

https://github.com/softwaretechnik-berlin/dbml-renderer
dbml-rendererはDBMLファイルをSVG画像にレンダリングします。
コマンドラインインタフェースを提供し、ドキュメント作成ツールチェインで簡単に使用できます。

事前準備

dbterd環境構築

pip install dbterd

dbml-renderer環境構築

dbml-renderer本体をインストールするのにnpmコマンドを使うので、一緒にインストールしちゃいます。

apt install nodejs
nodejs -v
apt install npm
npm install -g @softwaretechnik/dbml-renderer

dbterdでDBMLを作成し、dbml-rendererでDBMLをSVGとして画像形式のER図を生成する

dbterdコマンドでを使ってDBMLを生成してみます。

$ dbterd run -ad ./target/ -s model.jaffle_shop

オプションの紹介

オプションコマンド 概要
-ad dbtアーティファクトディレクトリ(/targetディレクトリ)へのパスを指定
-s dbterdコマンドの実行対象を指定する。モデルやスキーマなど
-ns 逆にdbterdコマンドの実行対象外を指定する

上記コマンドを実行すると、dbtのtargetディレクトリ配下にDBMLファイルが生成されます。
次にdbml-rendererを使って、DBMLファイルからSVG画像を生成します。

$ dbml-renderer -i output.dbml -o output.svg

実際に生成されたSVGファイルは以下のような表現になります。

dbterdでmermaid形式のER図を生成する

dbterdコマンドのオプションに-t mermaidを付与し、実行します。

$ dbterd run -t mermaid -ad target/ -s model

すると、target/配下にoutput.mdが生成されます。

続いて、mermaid用にマークダウンファイルを用意します。
以下コマンドを実行する。
./target/output.md -> このマークダウンファイルはdbterdコマンドで生成したファイル
./target/output2.md -> このマークダウンファイルはmermaid用に作成したファイル

$ echo \`\`\`mermaid > ./target/output2.md 
$ echo --- >> ./target/output2.md
$ echo title: Sample ERD >> ./target/output2.md
$ echo --- >> ./target/output2.md
$ cat ./target/output.md >> ./target/output2.md 
$ echo \`\`\` >> ./target/output2.md

output2.mdを確認すると、以下のように生成されました。

やってみた感想

0から自分でER図を作成するよりは簡単で良いなと思いました。
個人的にはmermaid形式にアウトプットするのが好きですね。
ただ、relationsip_testの記述からdbmlを生成しているようですが、複合キー(combination)の場合はどうなるんだろ?

Discussion