本番MySQLと開発MySQLのテーブル+カラムが一致しているか確認する(Perl,MySQL)
2013年5月2日
デプロイ時に、テーブルとかカラムを追加したり変更したりした時のtest用に。
use strict; use warnings; use Test::More; BEGIN{ use_ok('DBI') } BEGIN{ use_ok('Test::Fixture::DBI') } BEGIN{ use_ok('Test::mysqld') } my $db = 'myapp'; # 本番のDB sub dbh { return DBI->connect( 'dbi:mysql:'. $db .':localhost','db_user','db_password', +{ 'AutoCommit' => 0, 'RaiseError' => 1 } ); } # testのDB sub test_dbh { my $mysqld = shift; return DBI->connect( $mysqld->dsn( dbname => 'test' ), 'root','', +{ AutoCommit => 0, RaiseError => 1, }); } # testDBの作成 sub setup_test { my $mysqld = Test::mysqld->new( +{ my_cnf => +{ "skip-networking" => undef } }); my $test_dbh = test_dbh( $mysqld ); my $schema = construct_database( dbh => $test_dbh, database => 'schema.yaml', # testDBで作成したschema(下記参照) ); return $mysqld; } # 本番DB my $dbh = dbh(); # testDB my $mysqld = setup_test(); my $test_dbh = test_dbh($mysqld); # testDBのテーブル一覧 my $test_tables = $test_dbh->prepare('SHOW TABLES'); $test_tables->execute; for my $table ( @{ $test_tables->fetchall_arrayref(+{}) } ) { # 本番DBの該当テーブルのカラム my $column = $dbh->prepare('DESC '. $table->{'Tables_in_' . $db } ); $column->execute; my $release = $column->fetchall_arrayref(+{}); # testDBの該当テーブルのカラム my $test_column = $test_dbh->prepare('DESC '. $table->{'Tables_in_' . $db } ); $test_column->execute; my $test = $test_column->fetchall_arrayref(+{}); my $i = 0; for my $r ( @{ $release } ) { ok( $r->{'Field'} eq $test->[$i]->{'Field'} , $table->{'Tables_in_' . $db } . ' Field'); if ( $r->{'Default'} ) { if ( $test->[$i]->{'Default'} ) { # 同じか確認 ok( $r->{'Default'} eq $test->[$i]->{'Default'} , $table->{'Tables_in_' . $db } . ' Default(1)'); } else { # testのDefaultが無い -> err ok( 0 , $table->{'Tables_in_' . $db } . ' Default(2)' ); } } else { if ( $test->[$i]->{'Default'} ) { # testのDefaultがある -> err ok( 0 , $table->{'Tables_in_' . $db } . ' Default(3)' ); } } ok( $r->{'Type'} eq $test->[$i]->{'Type'} , $table->{'Tables_in_' . $db } . ' Type'); ok( $r->{'Null'} eq $test->[$i]->{'Null'} , $table->{'Tables_in_' . $db } . ' Null'); ok( $r->{'Key'} eq $test->[$i]->{'Key'} , $table->{'Tables_in_' . $db } . ' Key'); ok( $r->{'Extra'} eq $test->[$i]->{'Extra'} , $table->{'Tables_in_' . $db } . ' Extra'); $i++; } } # 本番DB切断 $dbh->disconnect; # testDB切断 $test_dbh->disconnect; done_testing();
schema.yamlの生成(Test::Fixture::DBI)
Test::Fixture::DBIをインストールすると、make_database_yaml.plコマンドが使えるようになるので、下記のコマンドでschema.yamlを生成します。
make_database_yaml.pl -d "dbi:mysql:myapp:localhost" -u root -o schema.yaml
ま、手動でデプロイしない限りは本番と開発で違うとかないと思いますが・・。