SchemaSpyのメタ情報をYAMLで書く
2019.12.23
SchemaSpyにメタ情報を追加するmeta.xmlをYAMLで書いてから生成するようにしてみた。
プロジェクト内でデータベースの構造をシェアするためによく SchemaSpy を使うのですが、新しいメンバーやクライアントに見てもらうにはコメントがないと読み解いてもらうのは簡単ではありません。
これについて、SchemaSpyではデーターベースに直接情報がなくても追加でXMLファイルを記述すればテーブルやカラムに対してコメントを追加することができます。
このXMLファイル自体はそんなに複雑ではないものの書くのか若干面倒だなと思っていたので、YAMLで同等の情報を書いてそれを元に生成するようにしてみました。
セットアップ
以下の手順はRailsプロジェクトで動作を確認しています。
- ruby: 2.6.5
- Rails: 6.0.1
Rakeタスクを追加
RailsプロジェクトにRakeタスクとしてYAMLをパースしてXMLを生成する処理を追加します。
$ bundle exec rails g task meta_xml
これで生成された lib/tasks/meta_xml.rake を以下のように編集します。
require 'nokogiri'
require 'yaml'
namespace :meta_xml do
desc 'meta.ymlからschemaspy用のmeta.xmlを生成'
task generate: :environment do
meta_yml_path = Rails.root.join('db/meta.yml')
meta_yml = YAML.load_file(meta_yml_path).with_indifferent_access
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
xml.schemaMeta('xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:noNamespaceSchemaLocation': 'http://schemaspy.org/xsd/6/schemameta.xsd') do
xml.comments meta_yml[:comments]
xml.tables do
meta_yml[:tables].each do |table, props|
xml.table(name: table, comments: props[:comments]) do
props[:columns]&.each do |column, comments|
xml.column(name: column, comments: comments)
end
end
end
end
end
end
meta_xml_path = Rails.root.join('db/meta.xml')
IO.write(meta_xml_path, builder.to_xml(indent: 2))
end
end
YAMLを書く
例として以下のようなテーブルの情報を db/meta.yml に書いてみました。
usersテーブルとtodosテーブル、それぞれのカラムについてコメントを記述しています。
comments: サンプルプロジェクトのデータベース
tables:
users:
comments: ユーザーテーブル
columns:
id: ユーザーID
email: メールアドレス
todos:
comments: TODOテーブル
columns:
id: TODO ID
user_id: ユーザーID
text: テキスト
XMLを出力
以上で bundle exec rake meta_xml:generate
と実行すると db/meta.yml の内容を元に以下のような db/meta.xml を出力できるようになりました。
<?xml version="1.0" encoding="UTF-8"?>
<schemaMeta xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schemaspy.org/xsd/6/schemameta.xsd">
<comments>サンプルプロジェクトのデータベース</comments>
<tables>
<table name="users" comments="ユーザーテーブル">
<column name="id" comments="ユーザーID"/>
<column name="email" comments="メールアドレス"/>
</table>
<table name="todos" comments="TODOテーブル">
<column name="id" comments="TODO ID"/>
<column name="user_id" comments="ユーザーID"/>
<column name="text" comments="テキスト"/>
</table>
</tables>
</schemaMeta>
あとはこれをSchemaSpyに読み込ませればOKです。