ある時、DBの定義書を確認したいと思い生成に成功したため実現方法を紹介します。
生成までの大まかな流れ
- mysqldumpでXML形式のダンプファイルを出力
- ダンプしたXMLファイルをHTML形式のファイルに変換
- HTML形式のファイルをPDFに変換
実装方法
XMLに変換するためのテンプレートファイルを用意します。
doc/db/schema/style/schema.xsl
<?xml version="1.0" encoding="utf8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://sqlfairy.sourceforge.net/sqlfairy.xml">
<xsl:output method="html" encoding="utf8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
<xsl:template match="database">
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>テーブル定義</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css" />
<style>
html body {
font-family: sans-serif !important;;
}
table.htable {
margin: 3em auto 1em auto !important;
}
table.htable th {
border-left: 10px solid #e5e5e5 !important;
}
footer {
border-top: 1px solid #e5e5e5;
padding: 0.5em;
}
</style>
</head>
<body>
<div class="container">
<h1 class="page-header">テーブル定義</h1>
<xsl:apply-templates select="table_structure" /> </div>
<footer class="text-center"> Created by showwin. </footer>
</body>
</html>
</xsl:template>
<xsl:template match="table_structure">
<table class="table table-bordered htable">
<tbody>
<tr class="active">
<th>テーブル名</th>
<td>
<xsl:value-of select="@name" />
</td>
<td>
<xsl:apply-templates select="options" />
</td>
</tr>
</tbody>
</table>
<table class="table table-condensed">
<thead>
<tr>
<th class="text-right">#</th>
<th>物理名</th>
<th>論理名</th>
<th>型</th>
<th>NULL</th>
<th>デフォルト値</th>
<th>主キー</th>
<th>ユニーク</th>
<th>その他</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="field" /> </tbody>
</table>
</xsl:template>
<xsl:template match="field">
<tr>
<td class="text-right">
<xsl:value-of select="position()" />
</td>
<td>
<xsl:value-of select="@Field" />
</td>
<td>
<xsl:value-of select="@Comment" />
</td>
<td>
<xsl:value-of select="@Type" />
</td>
<td>
<xsl:if test="@Null='YES'"><span class="glyphicon glyphicon-ok"></span></xsl:if>
</td>
<td>
<xsl:value-of select="@Default" />
</td>
<td>
<xsl:if test="@Key='PRI'"><span class="glyphicon glyphicon-ok"></span></xsl:if>
</td>
<td>
<xsl:if test="@Key='UNI'"><span class="glyphicon glyphicon-ok"></span></xsl:if>
</td>
<td>
<xsl:value-of select="@Extra" />
</td>
</tr>
</xsl:template>
<xsl:template match="options">
<xsl:value-of select="@Comment" /> </xsl:template>
</xsl:stylesheet>
生成はrakeコマンドで実行できるようにします。
lib/create_db_schema_document.rake
if Rails.env.development?
namespace :db_schema_document do
desc 'データベースの定義書をschemaディレクトリに作成'
schema_path = './doc/db/schema'
xml_schema_document = "#{schema_path}/schema_document.xml"
convert_xml_to_html_option =
"#{schema_path}/schema_document.html #{schema_path}/style/schema.xsl #{schema_path}/schema_document.xml"
convert_html_to_pdf_option = "#{schema_path}/schema_document.html #{schema_path}/schema_document.pdf"
task create: convert_html_to_pdf_option
# HTMLをPDFに変換
file convert_html_to_pdf_option => convert_xml_to_html_option do |task|
`wkhtmltopdf #{task.name}`
end
# XMLをHTMLに変換
file convert_xml_to_html_option => xml_schema_document do |task|
`xsltproc -o #{task.name}`
end
# schemaの構造をXML形式で出力
file xml_schema_document => %i[environment] do |task|
config = ActiveRecord::Base.connection_db_config.configuration_hash
options = {
h: config[:host],
P: config[:port],
u: config[:username],
p: config[:password],
}.compact.map { |k, v| "-#{k} '#{v}'" }.join(' ')
`mysqldump #{options} --no-data --xml '#{config[:database]}' > '#{task.name}'`
end
end
Rake::Task['db:schema:dump'].enhance do
Rake::Task['db_schema_document:create'].invoke
end
end
実行方法
xsltproc
とwkhtmltopdf
が使える環境であることを事前に確認しておきます。
bundle exec rails db:schema:dump
を実行するとデータベース定義書がschemaディレクトリ内に作成されます。
bundle exec rails db:schema:dump
でなく個別で実行する場合は、bundle exec rails db_schema_document:create
で生成することができます。