今回は ERAlchemy という ER 図を描くツールを使ってみる。 このツールは erd という Haskell で書かれた同様のツールにインスパイアされて作られたものらしい。 ただ、機能的にできることは ERAlchemy の方が多いみたいだ。
ERAlchemy が提供する基本的な機能は次の通り。
- ER フォーマットのテキストファイルから ER 図を生成する
- SQLAlchemy 経由で既存のデータベースから ER 図を生成する
後者の既存データベースから ER 図を生成するところなんかは、これまでだと MySQL Workbench を使ったりしてた。 ただ、このやり方だと文字通り MySQL でしか使えないのに対して ERAlchemy はそれ以外のデータベースにも対応している。 今回も試しに SQLite3 のデータベースから ER 図を生成してみている。 ただ、この機能が出力する図は、ちょっと直感には反する図になってしまった。
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.12.6 BuildVersion: 16G1114 $ python --version Python 3.6.3
インストール
まずは Homebrew を使って Graphviz を Pango と一緒にインストールしておく。
$ brew reinstall graphviz --with-pango
続いて ERAlchemy 本体をインストールする。
$ brew install eralchemy
ちなみに ERAlchemy 自体は Python で書かれているので pip 経由でインストールしても構わない。
$ pip install eralchemy
ER ファイルから ER 図を生成する
まず、基本となる使い方として ER フォーマットというテキストファイルから ER 図を生成してみる。 ER フォーマットの詳細については erd で詳しく説明されている。 とはいえ、ここでもその概要については説明する。
例えば、次の ER ファイルでは users
というテーブルの中に三つのカラムを定義している。
主キーとなる id
と、名前と年齢を入れる name
と age
だ。
$ cat << 'EOF' > example.er [users] *id name age EOF
上記を ER 図にレンダリングしてみよう。
eralchemy
の -i
オプションに上記のファイルを指定したら、出力先を -o
で指定する。
$ eralchemy -i example.er -o example.png
するとレンダリングされた画像が次のように生成される。
$ file example.png example.png: PNG image data, 89 x 159, 8-bit/color RGBA, non-interlaced
レンダリング先のフォーマットとしては画像ファイル以外に PDF にも対応している。
$ eralchemy -i example.er -o example.pdf
$ file example.pdf
example.pdf: PDF document, version 1.3
リレーションを表現する
リレーショナルデータベースの ER 図を描くのだから当然リレーションについても図示できないとまずい。 続いてはリレーションを含む ER 図を描いてみよう。
次の例ではテーブル users
とテーブル emails
が 1:n 対応しているところを表現している。
テーブルを定義してから、その後ろでそれらの関係性を書いていく感じ。
ちなみに本家の erd では外部キー参照を +
で表現するようだけど ERAlchemy ではまだサポートしていないようだ。
$ cat << 'EOF' > example.er [users] *id name age [emails] *id address user_id users 1--* emails EOF
上記をレンダリングしてみよう。
$ eralchemy -i example.er -o example.png
すると、次のような ER 図が得られる。
先の ER ファイルでテーブル間のリレーションを表現するのには --
の前後に対応関係を表す記号を入れていた。
この中で登場するのは 1
と *
だけだったけど、それ以外には ?
や +
も使うことができる。
意味 | 記号 |
---|---|
0 or 1 | ? |
exactly 1 | 1 |
0 or more | * |
1 or more | + |
型情報などのラベルをつける
リレーショナルデータベースの ER 図を描くのであれば、当然それぞれのカラムの型についても情報がほしい。
そういったときは次のように label
で情報を付与する。
$ cat << 'EOF' > example.er [users] *id {label: "INTEGER"} name {label: "TEXT"} age {label: "INTEGER"} [emails] *id {label: "INTEGER"} address {label: "TEXT"} user_id {label: "INTEGER"} users 1--* emails EOF
同様にレンダリングする。
$ eralchemy -i example.er -o example.png
上記から得られた ER 図は次の通り。
既存のデータベースから SQLAlchemy 経由で ER 図を描く
ERAlchemy の特徴として、SQLAlchemy 経由で既存のデータベースから ER 図を描く機能が挙げられる。 試しに SQLite3 のデータベースを作って、そこから ER 図を書いてみることにしよう。
まずは、次のように SQLite3 のデータベースを用意する。
$ sqlite3 example.db SQLite version 3.16.0 2016-11-04 19:09:39 Enter ".help" for usage hints. sqlite> CREATE TABLE users ( ...> id INTEGER NOT NULL, ...> name TEXT NOT NULL, ...> PRIMARY KEY (id) ...> ); sqlite> CREATE TABLE emails ( ...> id INTEGER NOT NULL, ...> address TEXT NOT NULL, ...> user_id INTEGER, ...> PRIMARY KEY (id), ...> FOREIGN KEY(user_id) REFERENCES users (id) ...> ); sqlite> .exit $ file example.db example.db: SQLite 3.x database, last written using SQLite version 3016000
用意ができたら ERAlchemy を使って ER 図をレンダリングする。
今度は -i
オプションに SQLAlchemy でデータベースの接続に使う URI 形式を渡すのがポイントとなる。
$ eralchemy -i sqlite:///example.db -o example.png
レンダリングされた図は以下の通り。
users
の方が 0...N になっていて、なんだから emails
の方が主体のような図になってしまった。
感覚的には反対になる気がするんだけどなあ。
まとめ
今回は ERAlchemy を使って ER 図を描いてみた。 既存のデータベースから ER 図を作る機能は、ちょっと「ん?」という結果になってしまった。 とはいえ ER ファイルから図をレンダリングする部分に関してはちゃんと動くみたいなので、上手く活用していきたい。