ブログ

ryuzeeによるブログ記事。不定期更新

Doctrine1でDBのマイグレーションを行う

みなさんこんにちは。@ryuzeeです。

アジャイルな開発を行って頻繁にデータベースのスキーマを変更したり頻繁にプロダクション環境にリリースしたりCIサーバで継続的にテストをしようとすると、データベース回りの変更をきちんと管理していくというのが非常に重要になります。

アマチュア的なアプローチだと毎回差分のsql文を書いて手でデータベースに食わせていくのですが、以下のような問題があります。

  • 複数のsqlを書いたファイルがあったとして、データベースの状態は実行順序に依存する可能性がある
  • SQLがRDBMSの仕様に依存する
  • 複数人で開発していると変更点を開発メンバーが認識して追随しているか判別しにくい
  • CREATEやALTERコマンドは書いていても、もとに戻すことは想定していないことが多いので、前バージョンに戻しにくい
  • 似た話で、あるリリースの時点でデータベースがどういうスキーマだったのかを再現するのが面倒
  • CI環境のDBを変更のたびに手でいじくるのは自動化の恩恵を生かしてない。そして手作業を忘れるとビルドが落ちるという悲しい話になる
  • 本番環境を手作業でいじくるのはミスの元

以下ではPHPにおけるマイグレーションのライブラリであるDoctrine1について手順を紹介しておきます。

なお、あえてDoctrine1を使ってる理由は、CakePHPのMigrationがイマイチ使いにくい(以前紹介したけど使わなくなった)のと、Doctrine2がSymfonyに依存しててインストールするモジュールが多すぎるためだったりします。

Doctrine1のインストール方法

これは簡単で、githubからライブラリを持ってきていくつかスクリプトを書けばOK。

ライブラリの入手

git clone https://github.com/doctrine/doctrine1.git

bootstrap.phpの作成

<?php

/**
 * Bootstrap Doctrine.php, register autoloader specify
 * configuration attributes and load models.
 */

require_once(dirname(__FILE__) . '/doctrine1/lib/Doctrine.php');

spl_autoload_register(array('Doctrine', 'autoload'));
spl_autoload_register(array('Doctrine', 'modelsAutoload'));
spl_autoload_register(array('Doctrine', 'extensionsAutoload'));

$manager = Doctrine_Manager::getInstance();

//SET ATTRIBUTES
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
$manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL);
$manager->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
$manager->setAttribute(Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);

// 以下は環境にあわせて変える
$dsn = 'mysql:dbname=testdb;host=localhost';
$user = 'root';
$password = 'root';
$dbh = new PDO($dsn, $user, $password);
$conn = Doctrine_Manager::connection($dbh);

?>

doctrine_cli.phpの作成

#!/path/to/php

<?php
require_once('bootstrap.php');

define('DATA_FIXTURES_PATH', dirname(__FILE__)."/data/");
define('MODELS_PATH', dirname(__FILE__)."/data/models/");
define('MIGRATIONS_PATH', dirname(__FILE__)."/data/migration_classes/");
define('SQL_PATH', dirname(__FILE__)."/data/sql/");
define('YAML_SCHEMA_PATH', dirname(__FILE__)."/data/schema/");

if(!file_exists(DATA_FIXTURES_PATH)) {
    @mkdir(DATA_FIXTURES_PATH, 0777);
}
if(!file_exists(MODELS_PATH)) {
    @mkdir(MODELS_PATH, 0777);
}
if(!file_exists(MIGRATIONS_PATH)) {
    @mkdir(MIGRATIONS_PATH, 0777);
}
if(!file_exists(SQL_PATH)) {
    @mkdir(SQL_PATH, 0777);
}
if(!file_exists(YAML_SCHEMA_PATH)) {
    @mkdir(YAML_SCHEMA_PATH, 0777);
}

// save configuration that have made in config.php to an array
$config = array('data_fixtures_path'  =>  DATA_FIXTURES_PATH,
                'models_path'         =>  MODELS_PATH,
                'migrations_path'     =>  MIGRATIONS_PATH,
                'sql_path'            =>  SQL_PATH,
                'yaml_schema_path'    =>  YAML_SCHEMA_PATH);

// use array configuration to Doctrine_Cli
$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
?>

使い方

既存DBからマイグレーションクラスファイルの作成

./doctrine_cli.php generate-migrations-db

→これによって現在接続中のデータベースからマイグレーションファイルが作成され、doctrine_cli.php内で定義されているMIGRATIONS_PATHフォルダに作成される

DBを指定の状態に更新する

バージョン1にする

./doctrine_cli.php migrate 1

最新バージョンにする

./doctrine_cli.php migrate

新しいマイグレーションファイルを作る

./doctrine_cli.php generate-migration hoge

これによってマイグレーションファイル置き場にXXXXXXX_hoge.phpというファイルが作成される。  

マイグレーションファイルの書き方については以下を参照すること http://www.doctrine-project.org/projects/orm/1.2/docs/manual/migrations/ja

Doctrine1の操作のまとめ

./doctrine_cli.php build-all

→Doctrineのモデル、SQLを生成し、データベースを初期化する

./doctrine_cli.php build-all-load

→Doctrineのモデル、SQLを生成し、データベースを初期化し、データをロードする

./doctrine_cli.php build-all-reload

→Doctrineのモデル、SQLを生成し、データベースを初期化し、データをロードする

./doctrine_cli.php compile

→Doctrineライブラリを単一に圧縮したライブラリ化する

./doctrine_cli.php create-db

→データベースを作成する

./doctrine_cli.php create-tables

→現在のモデルからテーブルを作成する

./doctrine_cli.php dql

→※これだけ分からん

./doctrine_cli.php drop-db

→データベースを削除する

./doctrine_cli.php dump-data

→データをダンプする

./doctrine_cli.php generate-migration [引数必須]

→指定した名前でマイグレーションクラスを作成する。

./doctrine_cli.php generate-migrations-db

→現在のDBとYAMLファイルを比較してマイグレーション用クラスを作成する

./doctrine_cli.php generate-migrations-diff [旧スキーマファイル(YAML)] [新スキーマファイル(YAML)]

→新旧のスキーマの差分からマイグレーションクラスを作成する

./doctrine_cli.php generate-migrations-models

→現在のDBとモデルを比較してマイグレーションを作成する

./doctrine_cli.php generate-models-db

→現在のデータベースからモデルを作成する

./doctrine_cli.php generate-models-yaml

→YAMLからモデルを作成する

./doctrine_cli.php generate-sql

→現在のDBからテーブル作成用のSQLを作成する

./doctrine_cli.php generate-yaml-db

→現在のDBからYAMLファイルを作成する

./doctrine_cli.php generate-yaml-models

→現在のモデルからYAMLを作成する

./doctrine_cli.php load-data

→Fixtureからデータをロードする

./doctrine_cli.php migrate

→migrationを実行する

./doctrine_cli.php rebuild-db

→DBをつくり直す

アジャイルコーチングやトレーニングを提供しています

株式会社アトラクタでは、アジャイル開発に取り組むチーム向けのコーチングや、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください。

詳細はこちら