MySQL Workbench の mwb ファイルから sql ファイルに自動変換

誰のための文書？
----------------------------

MySQL Workbench を使って DB のテーブル定義（ER 図作成）をしている人

mwb ファイルをバージョン管理下に置いているが、（バイナリなので）差分を確認できずにもやもやしている人

mwb をテキストとして扱うために内部の xml を頑張ってパースしている人

mwb でテーブル定義を管理するにあたって困ること
----------------------------------------------------

例えば下記のように `user` テーブルを作って `app.mwb` ファイルに保存し、`git add`, `git commit` したとします。
![Image 1.png](https://qiita-image-store.s3.amazonaws.com/0/3284/a0e628aa-67fe-3738-20fb-9a7e0424695d.png)

さて、その後開発が続き `article` テーブルを追加することになりました。
![Image 2.png](https://qiita-image-store.s3.amazonaws.com/0/3284/1e468b6e-b0f2-4a1a-33cf-6f7efaa5f03a.png)
`app.mwb` を上書きして `git commit -u` したとします。

さて、しばらく後にこの commit log を見た時に何がわかるでしょうか？
両リビジョン時点でのファイルを取得して Workbench で中身を確認すれば違いがわかるかもしれませんが、通常簡単に確認できるのはテキストファイルの差分だけです。（github の画像 diff のような mwb diff があれば良いのですが、現状そういうものはなさそうです）

mwb がバイナリならテキストにすればいいじゃない
-------------------------------------------------------------------

mwb のファイルそのもの（実体は zip で固められた xml ファイル）を解析して内部のテーブル定義を取り出すことも可能ですが、MySQL Workbench には実は `Lua` `Python` スクリプトインタフェースが搭載されています。今回はこれを使って mwb → sql の変換を行います。あとは、`git commit` するタイミングで hook して自動的に sql ファイルもバージョン管理下に入れてやれば良さそうです。バージョン管理システム上でどのように扱うかは各自工夫してみてください。

### 注意点
+ スクリプトインターフェースだけを使う場合も MySQL Workbench の GUI を起動するための「ディスプレイ」が必要
+ スクリプトインターフェースを使うためのドキュメントはほとんどない
+ GUI から SQL を export する場合は細かく出力内容を制御できるが、スクリプトインターフェースからダンプする場合は決められた形式でしか出力できない

1つ目の問題点については、MySQL Workbench を使うためだけに X WIndow System を入れるのは嫌なので、`Xvfb` 仮想フレームバッファを使用します。（Windows の場合は一瞬画面が現れますが諦めましょう）
2つ目については、今回 MySQL Workbench そのもののコードを眺めながら作ってみたので、本当に正しいのかは保証できません。
3つ目については、例えば DROP TABLE 文を追加する／しない、を GUI から制御できるのですが、スクリプトから操作するやり方は現状わかっていません。ただし、今回は差分をテキスト化して簡単に確認するのが目的なので、あまり問題にはなりません。

コード
-------------------

下記リポジトリに必要なコードとサンプル、使い方を置いています。本体である `mwb2sql.sh` に Python スクリプトも埋め込まれていますが、実質10行程度に収まっています。

https://github.com/tomoemon/mwb2sql

説明
--------------

### 環境
* WIndows (Windows7 で動作確認)
* Linux (Ubuntu12.04 で動作確認)

※ここでは Linux 上で GUI を表示せずに動かす方法を説明します。Windows の場合はもっと簡単なので上記リポジトリの README を参照してください。

### インストール

* mysql-workbench 5.2
* Xvfb

### 起動

Xvfb で仮想ディスプレイを有効にします。
Xvfb を起動すると font に関するメッセージが出てくるかもしれませんが、いったん気にしません。

```bash
$ Xvfb :1 &
[dix] Could not init font path element /usr/share/fonts/X11/cyrillic, removing from list!
```

この状態で :1 の仮想フレームバッファを使って MySQL Workbench を起動します。`mwb2sql.sh` の中にモデルをダンプするための Python スクリプトを記述してあるので、下記の通り起動すると、`a.sql` に  `test.mwb` 内で定義されているすべてのスキーマ、テーブルの CREATE 文が出力されます。

```bash
$ DISPLAY=:1 sh mwb2sql.sh test.mwb a.sql
```

仮想フレームバッファを使っているため、ssh 経由でつないでいる場合でも問題なく動くはずです。

`a.sql` に下記のような内容が出力されます。

```sql:
-- ----------------------------------------------------------------------------
-- MySQL Workbench Migration
-- Migrated Schemata: mydb
-- Source Schemata: 
-- Created: Thu Aug 01 02:32:15 2013
-- ----------------------------------------------------------------------------

SET FOREIGN_KEY_CHECKS = 0;;

-- ----------------------------------------------------------------------------
-- Schema mydb
-- ----------------------------------------------------------------------------
DROP SCHEMA IF EXISTS `mydb` ;
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;

-- ----------------------------------------------------------------------------
-- Table mydb.table1
-- ----------------------------------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`table1` (
  `id` INT NOT NULL ,
  `name` VARCHAR(45) NULL ,
  `created` DATETIME NULL ,
  `updated` DATETIME NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;
SET FOREIGN_KEY_CHECKS = 1;;
```

### git hook との連携

最後に、このスクリプトと git hook を組み合わせてテキスト化した sql ファイルを自動 commit しましょう。リポジトリ上の `git_pre-commit` ファイルをあなたが現在開発に使っているリポジトリの `.git/hooks/pre-commit` として置きましょう。

hook スクリプト内では仮想フレームバッファを使う指定がないので、DISPLAY の指定を export しておきます。hook スクリプトを書き換えても構いません。

```bash
$ export DISPLAY=:1
```

この状態で、開発中のリポジトリ内で任意の mwb ファイルを `git add`, `git commit` してみてください。`test.mwb.__auto_generated__.sql` のようなファイルが作成されて自動的に commit されるはずです。この場合は client-side hook ですが、server-side hook として使っても良いでしょう。

おまけ：Workbench を ER図を書くためだけに使っている人へ
----------------------------------------------------------------------------------

以前よりはだいぶ安定してきましたが、ちょっとした操作で **落ちることはまだまだ多い** ので、単純に図を書くためだけのツールとして使うにはあまりおすすめしません。ですが、DB サーバ上の実際のテーブルと mwb 上のモデルを同期したり、差分を取ったりと、Workbench ならではの機能がたくさんあるので、せっかく Workbench を使うならそれらの機能も使ってみることをおすすめします。