2013年1月10日

Yii Framework: データベースマイグレーションファイルを楽に書くには?

自分の中でまとまりつつあるので、データベースマイグレーションを楽に書く方法を書いていきます。

流れとしては以下。
  1. commandMap にてマイグレーションの設定を予め書いておく
  2. カスタマイズしたマイグレーションテンプレートを作成
  3. 既存のデータベースからマイグレーション用にスキーマをダンプしてくれるコマンドを作成
  4. マイグレーションのコマンドを実行し、ファイルを作成


1. commandMap にてマイグレーションの設定を予め書いておく

protected/config/console.php に commandMap を追加します。Yii Guide の ここ らへんで説明されています。テーブルのプレフィックス以外はガイドのやつと同じものですが、以下のように書きます。
<?php
return array(
...
'commandMap' => array(
'migrate' => array(
'class' => 'system.cli.commands.MigrateCommand',
'migrationTable' => 'migration',
'templateFile' => 'application.migrations.template',
),
),
...
view raw console.php hosted with ❤ by GitHub

2. カスタマイズしたマイグレーションテンプレートを作成

protected/migrations/ に template.php を作成します。どうやって作っていくのかを少し調べてみたんですが、情報が見つけられなかったので、自分になりにですが考えて、以下のようにしました。そのまんま php ファイルの雰囲気で書いて、クラス名だけ  {ClassName} にしただけですが (ちなみにこれそのまま実行すると Parse error が発生します) 。
<?php
class {ClassName} extends CDbMigration
{
public function safeUp()
{
$options = '';
if (Yii::app()->db->schema instanceof CMysqlSchema) {
$options = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';
}
}
public function safeDown()
{
}
}
view raw template.php hosted with ❤ by GitHub


3. 既存のデータベースからマイグレーション用にスキーマをダンプしてくれるコマンドを作成

これは Yii Guide のコメントにあったコードを元に少し追加したものです。これ です。
<?php
class DumpSchemaCommand extends CConsoleCommand
{
/**
* @see CConsoleCommand::getHelp()
*/
public function getHelp()
{
return <<<EOD
USAGE
yiic dumpschema <table_name>
EOD;
}
/**
* @see CConsoleCommand::run()
*/
public function run($args)
{
if (!isset($args[0])) {
$this->usageError('テーブル名を入力してください。');
}
$schema = $args[0];
$tables = Yii::app()->db->schema->getTables($schema);
$result = '';
foreach ($tables as $table) {
$result .= "// " . $table->name . "\n";
$result .= "\$this->createTable('" . $table->name . "', array(\n";
foreach ($table->columns as $column) {
$result .= " '" . $column->name . "' => '" . $this->getColumnType($column) . "',\n";
}
$result .= "), \$options);\n\n";
}
echo $result;
}
/**
* Gets the convert column type.
* @param string $column the column type
* return string the convert column type
*/
public function getColumnType($column)
{
if ($column->isPrimaryKey) {
return 'pk';
}
$result = $column->dbType;
if (strpos($column->dbType, 'int') !== false) {
$result = 'integer';
}
if ($column->dbType === 'tinyint(1)') {
$result = 'boolean';
}
if (strpos($column->dbType, 'varchar') !== false) {
$result = 'string';
}
if ($column->dbType === 'binary') {
$result = 'blob';
}
if (!$column->allowNull) {
$result .= ' NOT NULL';
}
if ($column->defaultValue !== null) {
$result .= " DEFAULT \'{$column->defaultValue}\'";
}
if ($column->comment !== '') {
$result .= " COMMENT \'{$column->comment}\'";
}
return $result;
}
}

4. マイグレーションのコマンドの実行し、ファイルを作成

あとは、php yiic migrate create init でマイグレーションファイルを作成して、 php yiic dumpshema <database_name> で出力されたものをマイグレーションファイルにコピペするだけです。インデックスなどは出力されないので、自分で追加していくことになります。

最後に php yiic migrate で完成!

0 件のコメント:

コメントを投稿