RDBテーブルの依存関係をPyreverseを使って(ほぼ手動で)可視化してみた

Pyreverseを使って、RDBのテーブルに限らず依存関係の可視化を簡単に行う方法を紹介します。
2020.08.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、平野です。
ずっと在宅で仕事しているので、郊外に引っ越したいです...!!

INSERT INTOをする複数のSQLクエリがあり、INSERTするレコードの取得に複数のテーブルを参照しているような場合、 その依存関係をひと目で確認できるグラフが欲しいです。 ですがPowerPointなどで自分で作るのはさすがにご勘弁願いたいということろで、 やり方を調べていた所、Pythonのパッケージ依存関係可視化のツールを使うというアイディアに行き着きました。

こういったグラフはGraphvizなどで描けることは知っていたのですが、 DOT言語の書き方などを一から学ぶのは辛いものがある。。。という状況でした。 その際、Pyreverseというツールを使うとすぐできたのでその方法を簡単にまとめます。

この記事ではあくまでも上記のような目的にPyreverseを使用したという内容であって、 Pyreverseの詳細な使い方については全然ご説明できる状態ではないので、そこんとこよろしくお願いします。

環境

  • macOS Catalina バージョン 10.15.6
  • Python 3.7.5
  • Graphviz 2.43.0
  • Pylint 2.5.3

必要なもののインストール

こちらを参考にしました。

Graphvizのインストール

最終的にグラフを描画しているのはGraphvizのようですので、インストールします。 Macの場合、brewでインストールできます。

brew install graphviz

Pyreverseのインストール

PylintをインストールすることでPyreverseもインストールされます。 pipでインストールを行います。

pip install pylint

依存関係を洗い出す(手動)

SQLから依存関係を洗い出します。 私が知る限り、あるクエリがどのテーブルに依存しているかは、 FROMJOINの後に続く単語だけを抜き出せば全て拾うことができそうです。 ここは手動となってしまいますが、依存関係を書き出しておきます。

注意点として、FROMJOINの後に(SELECT ...)のようなサブクエリが入っている場合もありますし、 またWITHで作成した一時テーブル名の場合もありますので、その辺は取捨選択する必要があります。

グラフを出力してみる

依存関係をPythonのパッケージ依存関係に落とし込む

以上で準備は完了です。 あとはSQLのテーブル依存関係をPythonのパッケージの依存関係に置き換えてファイルを配置します。

例えば、テーブルaaaがテーブルbbbに,bbbcccに依存しているとすると、

aaa.py

import bbb

bbb.py

import ccc

ccc.py

# empty file

というファイル群を同じディレクトリ内に配置します。 カラのファイルも配置する必要があるという点もポイントです。

最後に、このディレクトリにカラの__init__.pyというファイルも設置します。 これがないとPyreverseが他のファイルをうまく見つけてくれないようです。

さて、いよいよPyreverseを実行します。 実行は簡単で、__init__.pyがあるディレクトリで以下を実行します。

pyreverse -o png .

するとこのディレクトリにclasses.pngpackages.pngが出力されます。 packages.pngこそが目的のグラフとなります。

左下の__init__は依存関係とは関係ないのですが、ちょっと消し方がわかりませんでした。 依存の構造を考慮して、ある程度いい感じに配置してくれます。 矢印の向きとしては、needsという意味だと考えるとしっくりきます。

出力ファイルの形式として今回はpngを指定しましたが、 epsなどを指定すればベクター形式のファイルを得ることもできます。

少し大きい規模の例

今回欲しかったテーブルの依存関係はこんな感じになりました。

要素数もある程度あり、依存関係もそんなにわかりやすい形ではなかったので、 可視化することによって依存関係の確認をする際に役立ちました。 これくらいになるとグラフがないとちょっと把握するのが辛くなってくるレベルですね。

課題点

テーブル名が長いと可視性が下がる

今回の例はaaaのような、通常ではありえないほど短い名前を使ったので、 規模がある程度あっても見栄えはよくなっています。 しかし実際にはそんなに短いテーブル名ばかりが使われることは滅多にないので、 実際に出来上がるグラフはもっと横長になってしまうかと思います。 場合によっては名前を省略名に変えるなどの対応をした方が良さそうです。

スキーマでグルーピングしたい

テーブルが複数のスキーマにまたがっている場合、それでグルーピングした表示をしたい場合もあるかと思います。 __init__.pyにうまく書いたりすればできそうなのですが、ちょっとうまくやる方法がわかりませんでした。

まとめ

テーブルの依存関係を、PythonのPackageの依存関係を可視化できるPyreverseを使用して行ってみました。 別にテーブルに限った使い方に限定されるわけではないので、 複数の要素の依存関係を可視化したい用途に使えると思います。

また今回はSQLから手動で頑張って依存関係を洗い出すという作業が入ってしまいました。 これは正規表現を使用したり、クエリをパースするなどでSQLを解析することで自動化できそうなので、 そういったスクリプトも今後書いておきたいと思っています。

多分こういうことって、複数のSQLファイルをガッツリ解析してくれるようなツールがあれば、 それで可視化してくれるのだと思いますが、 そういった大きなツールは学習コストも高くて、ちょっと身構えてしまうんですよね。。 私はこれくらいその場その場でちょっとだけ可視化するとかいう道具を揃える方が好きなのでこんな方法を試してみました。

以上、誰かの参考になれば幸いです。