(24日目) schema2rst と Sphinx でお手軽データベース定義書作り

ここ数日 blockdiag の話が続いていましたが、久しぶりに Sphinx の話に戻ります。

僕は Sphinx を使ってお仕事のドキュメントを書いているので、
ドキュメントのひとつとしてデータベース定義書を書くことがあります。
このデータベース定義書、みなさんはどうやってメンテナンスしていますか?

以前、僕のチームでは Excel で定義書を作っていたのですが、
定義書と実際に稼動しているスキーマが異なることが稀にあり、
混乱が生したり、ちょっとしたトラブルの元になることがありました。*1

よく考えてみると、データベース定義書とスキーマを二重に管理しなくてはならないので、
どこかで同期に失敗すると(更新忘れなど)そこに差ができてしまうのは自明なことです。

一部の企業では Excel から DDL を書きだすようなマクロを持っているそうですが、
差分更新ができないなどでうまくメンテナンスされていないという話を聞きます。

問題のもととなっているのは

  • データベース定義とスキーマを二重管理していること
  • 最新の情報であるか確認する術がないこと

のふたつです。

schema2rst

そこで、問題を解決するべく schema2rst というツールを開発しました。
名前の通り、スキーマ定義から reST ファイルを生成するツールです。
schema2rst を利用することで、問題のもととなるふたつを根本から解決することができます。

schema2rst 自体はずっと前にたたき台になるものを開発してありましたが、
この記事を書くために昨日ようやくリリースしました。
今読み返すとほぼ一年間放置してあったようです。

テスト用のデータベースを作る

schema2rst 0.1.0 (最新版)は MySQL をターゲットに作られているので、
MySQL に次のようなデータベースとテーブルを作成します。

CREATE DATABASE sample CHARACTER SET utf8;

作成するテーブルは 4つです。

  • users (ユーザ)
  • items (商品)
  • order_history (購入履歴)
  • uncommented_table (テスト用/MySQL コメントなし)
DROP TABLE IF EXISTS users, items, order_history, uncommented_table;

CREATE TABLE users (
  id int primary key auto_increment comment 'ユーザ ID',
  login_id varchar(16) default '' not null comment 'ログイン ID',
  fullname varchar(255) default '' not null comment '氏名',
  mailaddr varchar(255) default '' not null unique comment 'メールアドレス',
  key (mailaddr)
) ENGINE='InnoDB' COMMENT 'ユーザ';

CREATE TABLE items (
  id int primary key auto_increment comment '商品 ID',
  name varchar(255) not null comment '商品名',
  type int not null default 1 comment '種別 (1:食品, 2:文具, 3:雑貨)',
  description text comment '説明文'
) ENGINE='InnoDB' COMMENT '商品';

CREATE TABLE order_history (
  id int primary key auto_increment comment '履歴 ID',
  user_id int not null comment 'ユーザ ID',
  item_id int not null comment '商品 ID',
  amount int not null comment '数量',
  order_date datetime comment '購入日',
  index (user_id, order_date),
  index (item_id, order_date),
  foreign key (user_id) references users(id),
  foreign key (item_id) references items(id)
) ENGINE='InnoDB' COMMENT '購入履歴';

CREATE TABLE uncommented_table (
  id int primary key auto_increment,
  name varchar(255) binary
) ENGINE='InnoDB';

DDL をよく見ると、COMMENT 文を利用しています。
ちょっとマイナーな存在ですが、MySQL ではテーブルやカラムに対してコメントを付与することができるので、
schema2rst ではこのコメント領域を利用してテーブルやカラムの日本語名の情報、
制約などの情報をスキーマから取得します。
schema2rst を利用する際はなるべくコメントを利用して、
詳細にスキーマ定義を行うことを推奨します。

schema2rst でスキーマ情報を取り出す

schema2rst は easy_install でインストールすることができます。

$ sudo easy_install schema2rst

インストール後、schema2rst の設定ファイルを作成します。
設定ファイルはデータベースへの接続情報を YAML 形式で記述します。

$ vi config.yaml
db: sample
host: localhost
passwd: passwd
user: username

最後に schema2rst を実行します。引数には先ほど作成した設定ファイルを指定します。

$ schema2rst config.yaml > schema.rst

生成された schema.rst にはデータベース定義の情報が含まれています。
サンプルとして items テーブルの情報はこんな感じで出力されます。

商品 (items)
------------

.. list-table::
   :header-rows: 1

   * - Fullname
     - Name
     - Type
     - NOT NULL
     - PKey
     - Default
     - Comment
   * - 商品 ID
     - id
     - int(11)
     - False
     - True
     - None
     - auto_increment
   * - 商品名
     - name
     - varchar(255)
     - False
     - False
     - None
     -
   * - 種別
     - type
     - int(11)
     - False
     - False
     - '1'
     - 1:食品, 2:文具, 3:雑貨
   * - 説明文
     - description
     - text
     - True
     - False
     - None
     -

reST では list-table を使っているのでパッと見では分かりづらいですね。
どのような出力になるか把握しやすいよう、Sphinx でビルドしたものも用意しました。

先程の DDL 文と見比べて、同等のデータベース定義が取り出せています。
MySQL のコメントがないテーブル・カラム(uncommented_table)も
必要な情報は列挙されています。
コメントがない状態でも最低限のデータベース定義はすぐ生成できます。

まとめ

schema2rst を利用すると DB 上のスキーマ定義情報から直接データベース定義書を作成することができます。
いまのところ MySQL にしか対応していませんが、今後他の DBMS にも対応していくつもりです。*2
興味が有る方は一度使ってみてはいかがでしょうか。

いよいよ明日 12/25 でこのアドベントカレンダーもおしまいです。
せっかくですので、どうかもう一日だけお付き合い下さい :-)

*1:幸い大きいトラブルになったことはありません。幸運なだけかもしれませんけど。

*2:考えてはいますが、僕自身は MySQL ばかり使っているので他のエンジンへの対応は>のんびりやるつもりです