読者です 読者をやめる 読者になる 読者になる

エンジニアの箱

サーバ構築とか、Ciscoルータの設定とか、コーディングに関してのなにがしを書きます。

RDBのマイグレーションを半自動化しようとあがいている話

新年あけました。おめでとうございました。

私は大みそか前日から正月休み丸々コーディングに費やした(プライベートで)ので全く年明け感がないです。ようやく年明け感がでてくるかなーという1月中旬に喉の激痛でぶっ倒れました。新年早々なにしてるんじゃ。

最近やっていることの話

まぁとりあえず生きてる

いろいろやってます。プライベートで。現状はvagrant+ansibleでローカルの開発環境を自動化しているところです。他にもWebアプリを作っていて、それのDBマイグレーションとかをゴリゴリ自動化してます。自動化きもちいい。この記事はそれの話です。

要するに自動化おじさん

まだ四捨五入したら20歳なのでおじさんではないのですが、まだおじさんではないのですが、とにかく自動化してます。私は単純作業が死ぬほど苦手で手順が5つ以上あったら絶対にミスります。なので自動化。

どんな自動化?

DDLを所定のディレクトリに配置すると、DDLに従ってDBを書き換えてくれる君です。誰だ今大したことないって言った奴。まぁこの段階では大したことないんだけどね…。

まず使ってるDBツールを紹介するよ

私はA5M2というSQL/E-R図開発ツールを使っています。なぜかっていうと、これ一つですべてできるから。E-R図が書ける(しかも論理名も表示できる!)、SQL実行できる、当然DB接続もできる、SSHトンネル経由の接続もできる、値の書き換えもできる、DB定義書の出力もできる、と至れり尽くせり。なんといってもE-R図からDDLを生成できるのはでかい。

でもここが不便

ただ当然のことながら不便なところがないわけじゃない。というよりはこれはもうどうしようもない話だと思うんだけど、E-R図で新たに変更があった部分だけをDDL出力することができない。つまり、初回は

  1. E-R図を作成
  2. DDLを生成
  3. DBに反映
  4. みんなハッピー

になるんだけど、2回目以降は

  1. E-R図を修正
  2. DDLを生成
  3. 前回出力したDDLと新しく生成したDDLを見比べてALTER TABLEを作成する
  4. ALTER TABLEでDBに反映

ってなるから、死ぬほどめんどくさい(もちろんソースも修正しなけらばならない。)。特に開発環境でローカルDB持つ形式だと、DROP DATABASEもできないのでなんとかALTER TABLEで頑張るか、マイグレーション用のSQLを書くしかない。そんな面倒なことやってられっか!!
この世からすべての手作業を消し去りたいマン(つまり死ぬほどめんどくさがりマン)なので、何とか自動化しようとしてあがいた話。

方針

まとめると、こう。

  1. 既存のマイグレーションツール「south」を使うよ(Djangoが内包)
  2. テンポラリDBと開発環境用DBを分けるよ

結論から言って、マイグレーションツールを作ろうなんて話になると果てしなき長い道のりになるので既存のマイグレーションツールを使いましょうということ。私の場合、WebフレームワークでDjangoを使っているため、Djangoに内包されているsouthというマイグレーションツールを利用することになります。つまりDjango使ってる人向け。

あとは、テンポラリDBという概念を導入。どうしても内部でデータを保持しておく必要があるので、仮にDROP DATABASEなんてやった日には、データをINSERTしなおさないといけない。
もしDROP DATABASEをしないとなると、ALTER TABLEしないとなのでこれもあり得ない(面倒)。じゃあもう最初からデータを保持しないDBを構築しておいて、これは変更反映用のDBとしてのみ使用、開発環境用DBはマイグレーションツールによる変更1択で任そうよっていうこと。
Djangoの場合、Entityのような形で記述する(DBと1対1のメンバ変数を持つクラスのやつですよ。)models.pyというものがあり、このファイルを変更後所定のコマンドをたたくことでDBのマイグレーションを行なってくれる仕組みになっている。ということは、テンポラリDBを変更後、テンポラリDBからmodels.pyを自動生成し所定のコマンドをたたけば開発環境用DBも書き換わるということ。イコールで、E-R図を変更してDDLを所定の場所に配置するだけでDBのマイグレーションが行なわれる、となるカラクリだ。

全体のフロー

  1. A5M2でE-R図を修正する(手動)
  2. DDLを生成する(手動)
  3. 所定のディレクトリへDDLを保存(手動)
  4. cronが走りテンポラリ用のDBを更新(自動)
  5. テンポラリDBから情報を抽出しmodels.pyを自動生成(自動)
  6. models.pyの情報を元にDjango内包のsouthによりDBマイグレーション(自動)

とまあこんな感じ。DBマイグレーション自体は失敗することもあるみたいなので、この辺は柔軟に対応する必要はあるにせよ、ほぼ手作業が介入しない状態に。

E-R図必要?

絶対必要です。正直DB定義書よりほしい。DB定義書なぞ最悪自分でクエリ書いて自動生成すれば済む話で、E-R図だけはそうもいかない。それに直感的にDB構造を把握するために必要。 なので今回のような大掛かりな自動化を施したわけです。Django使っている以上、本来であればmodels.pyの修正でいいっちゃいいんですけどね。どうしてもE-R図がほしかったので。

ちなみに

自動化って言ってるけど、これ実際は2つの自動化があって、1つ目は説明した通り「DBの変更を自動化」ってことです。そして2つ目は「設計書と実装を自動的に揃える」ってこと。もちろんE-R図を直すっていう工程を先にしないと成り立たないんだけども、それさえ守ればE-R図と実装は必ずイコールになる。どの現場でも設計書と実装がズレていくと思います。それは個人レベルでも起こりうるというか、個人レベルだからこそ時間がないがゆえに起こりやすいのではないかと。 そういったものも含め今回のカラクリを作成。これで面倒な手作業から解放されると思うと…。ただまだ5.6.をシェルスクリプトに乗っけられてないので、それはやらないといけないです。さくっとやろう。