はい、kawamotoです
皆さん仕事でデータベースを触っていると本番環境、検証環境、開発環境など、複数の環境を扱うことになりますよね。
複数の環境を扱っていると環境によってテーブルのスキーマの差分ができてしまうのを防ぐ必要が生じます。
今回は、複数の環境の整合性を保つ方法について考えてみたいと思います。
要件を列挙してみます。上の方が優先度高めです。
探すのが大変だったのですが、今回はどうにか見つけたDBIx::DBSchemaをご紹介します。
ちょっとサボろうかと思ってぐぐってみたのですが、このモジュール、全く言及されていません。早くも不安がよぎります・・・
こんなコードを書いてみました。
use strict; use DBI; use Data::Dumper; use DBIx::DBSchema; my $user = 'user'; my $pass = 'password'; my $dbh1 = DBI->connect('DBI:mysql:database=test_kawamoto;host=localhost', $user, $pass); my $dbh2 = DBI->connect('DBI:mysql:database=test_kawamoto2;host=localhost', $user, $pass); my $schema1 = new_native DBIx::DBSchema $dbh1; print Dumper $schema1; # Storable で保存される $schema1->save('/tmp/test_kawamoto'); my $actor1 = $schema1->table('actor'); my $actor2 = $schema1->table('actor2'); print $actor2->sql_alter_table($actor1, $dbh1); print $actor2->sql_create_table($dbh1);
使い方はそこまで難しくありません。
my $schema1 = new_native DBIx::DBSchema $dbh1;
これでスキーマの情報を $dbh1 から吸い出します。
$schema1->save('/tmp/test_kawamoto');
とやればStorable形式でデータを出力します。
print $actor2->sql_alter_table($actor1, $dbh1);
とすると以下のような出力を得ます。CREATE INDEX 書いてくれた!
CREATE INDEX idx_actor_first_name ON actor2 ( first_name )
続いて
print $actor2->sql_create_table($dbh1);
とやると以下のような出力を得ます。CREATE文ももちろん書ける!
CREATE TABLE actor2 ( PRIMARY KEY (actor_id) ) CREATE INDEX idx_actor_last_name ON actor2 ( last_name )
何かおかしいとおもったら、どうやらcolumnsの取得に失敗しているようです・・・
これはおそらくMySQLの対応が中途半端になっている可能性が・・・
ドキュメントを見るかぎり、Oracle、 Pg、 SQLite、 Sybase、 mysqlに対応しているそうですが、これは残念。
いいところまでいったところですが時間切れなので今回はこれまでにしておきます。
CPAN内を探しまくって見つけたアタックリストが以下です。誰得な感じがしますがせっかくなので大公開します。
少し改造が要りそうですが、このモジュールを使って簡単なアプリを書けば複数環境のスキーマの管理ができそうな気がします。ちょっと中途半端ですみません。モジュールを探すのが大変すぎて力尽きました。
お次はおそらく s_ohira さんです。お楽しみに!