データベースドキュメント生成コマンド tbls 更新情報 ( PostgreSQL publicスキーマ表示仕様変更/Amazon DynamoDB対応/goccy ware etc)

ここ最近tblsのアップデートエントリを書いていなかったのですが、最近変更をいくつか行いました。

このまま放置するとちょっと紹介しきれなくなりそうなので、ここら辺で放出しておこうと思います。

紹介時点のtblsのバージョンはv1.29.0です。

PostgreSQLでの public. スキーマ表示仕様変更

tblsでは、もともとPostgreSQLpublic. スキーマschema_name.table_name.column_nameschema_name )だけ特別に非表示にしていました。

こうなっていた理由は、私がPostgreSQLでのスキーマを意識した運用経験がなかったことに寄る部分が大きいです。「デフォルトだから非表示で良いだろう」と。

ところで、tblsにはlintの機能があります。「テーブルカラムにコメントが書かれているか?」とか「外部キーの参照元にINDEXが張られているか?」とか。

そのlint機能に対して「public. スキーマだけexcludeしたいができない」というIssueが立てられました。

github.com

tbls lint が提供しているルール*1には「このテーブル名/カラム名の場合だけ除外する」という除外設定があるのですが、tblsでは publc. が非表示なので、 exclude: public.* みたいな書き方ができないというものです。

なるほど。。。確かに。。。ということで「時間をください」とだけ伝えて検討することにしました。

とはいえ上記で書いたように私には経験がないのでいろいろ悩んだ挙句、有識者のいるであろうSlackのpostgresql-jpで質問してみることにしました*2

わかったことは

  • スキーマは積極的に、有効に使われていることがわかりました。スキーマを利用して様々な意図でグルーピング(Namespaceを切るようなもの?)をしているとのことでした。また、 public. を意図して使わない方も。
  • そもそも public.厳密にはデフォルトではない"5.8.3. スキーマ検索パス" )ということも教えていただきました。

ということで、完全にtblsの実装が良くないと判断できたので public. スキーマも他のスキーマと同様に表示するように変更しました。

v1.28.0から適用されています。

Amazon DynamoDBに対応

Amazon DynamoDBにも対応しました。

DSNは

dynamodb://[aws_region]

とシンプルです。

そして、Amazon DynamoDBに対応するために、合わせて次に紹介する2つの機能をリリースしました。

include: テーブルをフィルタリングする機能を追加

Amazon DynamoDBにはテーブルをグルーピングする「データベース」や「PostgreSQLスキーマ」のようなくくりはありません。同一リージョンであれば、aws dynamodb list-tables コマンドなどで全てのテーブルがリストされます。

今時はAWSアカウントをアプリケーション分作成することが多いと思うのですが、例えば同一アカウント同一リージョンで複数のアプリケーション用のDynamoDBテーブルの運用をしているときなど、tblsでドキュメント化するテーブルを絞り込みたいことがあるだろうと考えました。

そこで、もともとあったテーブルフィルタリング機能 exclude: に加え include: を設定できるように機能を追加しました。

include:exclude: との関係は以下の図のようになっています。

f:id:k1LoW:20200314142527p:plain

これを利用することで、tblsで管理するテーブルを柔軟に絞り込むことが可能になっています。

dict: ドキュメントタイトルやテーブルヘッダの文字列を変更する機能を追加

これもAmazon DynamoDB対応を契機に設計をしたものです。

Amazon DynamoDBにおいて、TableTable なのですが、RDBにおける Column はDynamoDBでは Attribute 、制約( Constraints ) もPrimary Keyしかないですし、 Index も正確には Secondary Index です。

DynamoDBのドキュメントも上記の単語を使いたいと考えていました。

また、ユーザも表記を変えたいことがあるだろうと考えて dict: を追加しました。

これは、単語と単語の変換用辞書を設定できるというものです。例えば以下のように .tbls.yml に設定すると tbls doctbls out -t xlsx で出力されるドキュメントが日本語化されます。

# .tbls.yml
---
dict:
  Tables: テーブル一覧
  Description: 概要
  Columns: カラム一覧
  Indexes: INDEX一覧
  Constraints: 制約一覧
  Triggers: トリガー
  Relations: ER図
  Name: 名前
  Comment: コメント
  Type: タイプ
  Default: デフォルト値
  Children: 子テーブル
  Parents: 親テーブル
  Definition: 定義
  Table Definition: テーブル定義

上記に加え、各データベースへ接続するためのドライバにもデフォルトの辞書を内部に持たせるようにすることでAmazon DynamoDBのドキュメントの場合だけ AttributeSecondary Indexes と表記できるようにしました。

distance: ER図として表示する隣接するテーブルの距離を設定できる機能を追加

tbls doc で生成されたドキュメントの各テーブル定義のmdには、そのテーブルを中心として隣接したテーブルをレンダリングしたER図を表示しています。

ただ、ここの表示が隣のテーブルまで(距離1)で固定でした。

PlantERDというCLIツールがあります。

github.com

データベースに接続し情報取得しER図を出力するのですが、出力フォーマットにPlantUMLを選択することで 文字列なのに視覚的にいい感じに 、 それをGitで管理することによって スキーマ変更前後の差分もいい感じに 把握できるという特徴があります。

このPlantERDの作者の sue445 さんのPlantERDリリースと実装(経緯とか方針とか)についての紹介エントリを読んで、tblsと近い部分(複数DBのつらみとか)に共感しつつ、

sue445さんの「特定のテーブルに隣接するテーブルのみを抽出して実装把握のための情報にする *3 」という手法に「なるほど!」と納得しつつ、「distance良いな」と、tblsにも実装しました。

.tbls.yml での設定は以下のような感じです(デフォルトは 1 )。

# .tbls.yml
er:
  distance: 2

また、 tbls out コマンドにも --distance オプションを追加していますので、以下のようなテーブルのER図を出力するような場合には有効になります。

$ tbls out -t svg --table users --distance 2 -o users.svg

Graphvizdot コマンド依存の脱却

tblsはER図の生成にGraphvizdot コマンドを外部コマンドとして利用していましたが goccy さんの goccy/go-graphviz を利用することでtbls内にER図生成機能を内包できるようになりました。

github.com

これによりtblsのポータビリティがさらに上がりました。

これ、上記紹介だとたった3行ですけど、go-graphvizが実現していること相当すごいですよね...

READMEの"How it works"にgo-graphvizアーキテクチャが簡単に紹介されていますので興味ある人は是非。

YAMLパッケージ goccy/go-yaml の採用

go-graphviz に続き goccy ware です。

なぜ goccy/go-yaml なのか

tblsは設定ファイル .tbls.yml のフォーマットにYAMLを採用しています。

そして実際にtblsでプロダクションレベルのデータベースのドキュメントを運用すると、その .tbls.yml がどんどん肥大化していきます。

これについては課題と考えており、その解決方法としてYAMLのアンカーやエイリアスの機能だけでなくYAMLファイル分割のサポートが必要になりそうだと考えていました。

そして、この課題を解決してくれそうなポテンシャルを持っているYAMLパッケージとして goccy/go-yaml を採用しました。

詳しくは以下のQiitaのエントリが(作者本人の紹介ということもあり)詳しいです。

qiita.com

v1.29.0時点ではまだgo-yaml/yamlからgoccy/go-yamlに差し替えただけですが、これからの機能開発時に真価を発揮すると思っています。


というわけで、駆け足でtblsの最近のアップデートの紹介でした(紹介していない機能追加もあります)。

tblsの利用分布はGitHub Starを見ると日本だけに集中しているわけでもなく世界中でまんべんなく使われている(?)ようです。これは嬉しい事実です。

データベースドキュメント*4がCIで最新であり続ける状態が普通になると良いなと思っています。

まだ実装したい機能はあるので、引き続きじっくり開発を進めたいと思います。

*1:RubocopのCopみたいなものです

*2:postgresql-jpのみなさん、突然の私の質問に知識や経験を共有していただいて本当にありがとうございました

*3:実はtblsも "tbls out -t plant_uml --table users" でPlantUMLを出力できるのですが、v1.29.0時点ではINDEX情報が出力されないなど、PlantERDが持つ「PlantUMLのみで把握する」という目的はカバーできません

*4:私はスキーマ情報だけでなくそれに付随する情報も合わせて初めてドキュメントだと考えています