データベース駆動型アプリケーションの開発と保守において、使用されているデータベースの構造はソースコードと同様に進化します。例えば、アプリケーションの開発中に新しいテーブルが必要になる場合や、アプリケーションを本番環境にデプロイした後、クエリの性能を向上させるためにインデックスを作成する必要があることが判明する場合などがあります。データベース構造の変更は多くの場合、ソースコードの変更も必要とするため、Yiiは、ソースコードと共にバージョン管理されるデータベースマイグレーションという形で、データベースの変更を追跡できる、いわゆるデータベースマイグレーション機能をサポートしています。
次の手順は、開発中にチームがデータベースマイグレーションをどのように使用できるかを示しています。
そして、次の手順は、データベースマイグレーションを使用して新しいリリースを本番環境にデプロイする方法を示しています。
Yiiは、次のことを可能にするマイグレーションコマンドラインツール一式を提供します。
これらのツールはすべて、コマンドyii migrate
からアクセスできます。このセクションでは、これらのツールを使用してさまざまなタスクを実行する方法について詳細に説明します。各ツールの使用方法については、ヘルプコマンドyii help migrate
で確認することもできます。
ヒント:マイグレーションは、データベーススキーマだけでなく、既存のデータを新しいスキーマに適合させる、RBAC階層を作成する、またはキャッシュをクリーンアップするなどの影響を与える可能性があります。
注記: マイグレーションを使用してデータを操作する場合、一部のロジックが既に実装されているため、アクティブレコードクラスを使用すると便利な場合があります。ただし、マイグレーションで記述されたコードは常に一定であるのに対し、アプリケーションロジックは変更される可能性があることに注意してください。そのため、マイグレーションコードでアクティブレコードを使用する場合、アクティブレコードレイヤーのロジックの変更によって、既存のマイグレーションが誤って破損する可能性があります。このため、マイグレーションコードは、アクティブレコードクラスなどの他のアプリケーションロジックとは独立して維持する必要があります。
新しいマイグレーションを作成するには、次のコマンドを実行します。
yii migrate/create <name>
必須のname
引数は、新しいマイグレーションに関する簡単な説明を与えます。たとえば、マイグレーションがnewsという名前の新しいテーブルの作成に関するものである場合、create_news_table
という名前を使用し、次のコマンドを実行できます。
yii migrate/create create_news_table
注記:
name
引数は生成されたマイグレーションクラス名の一部として使用されるため、英字、数字、および/またはアンダースコア文字のみを含める必要があります。
上記のコマンドは、@app/migrations
ディレクトリにm150101_185401_create_news_table.php
という名前の新しいPHPクラスファイルを作成します。このファイルには、主にスケルトンコードを含むマイグレーションクラスm150101_185401_create_news_table
を宣言する次のコードが含まれています。
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
}
public function down()
{
echo "m101129_185401_create_news_table cannot be reverted.\n";
return false;
}
/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}
各データベースマイグレーションは、yii\db\Migrationから拡張するPHPクラスとして定義されます。マイグレーションクラス名は、m<YYMMDD_HHMMSS>_<Name>
の形式で自動的に生成されます。ここで
<YYMMDD_HHMMSS>
は、マイグレーション作成コマンドが実行されたときのUTC日時を表します。<Name>
は、コマンドに指定したname
引数の値と同じです。マイグレーションクラスでは、データベース構造に変更を加えるup()
メソッドにコードを記述する必要があります。また、up()
によって行われた変更を元に戻すdown()
メソッドにコードを記述することもできます。up()
メソッドは、このマイグレーションを使用してデータベースをアップグレードしたときに呼び出され、down()
メソッドはデータベースをダウングレードしたときに呼び出されます。次のコードは、news
テーブルを作成するためにマイグレーションクラスを実装する方法を示しています。
<?php
use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
$this->createTable('news', [
'id' => Schema::TYPE_PK,
'title' => Schema::TYPE_STRING . ' NOT NULL',
'content' => Schema::TYPE_TEXT,
]);
}
public function down()
{
$this->dropTable('news');
}
}
情報: すべてのマイグレーションが可逆であるわけではありません。たとえば、
up()
メソッドがテーブルの行を削除した場合、down()
メソッドでこの行を回復できない可能性があります。データベースマイグレーションを元に戻すことはあまり一般的ではないため、down()
を実装するのが面倒な場合があります。この場合、down()
メソッドでfalse
を返すことで、マイグレーションが可逆ではないことを示す必要があります。
基本マイグレーションクラスyii\db\Migrationは、dbプロパティを介してデータベース接続を公開します。これを使用して、データベーススキーマの操作で説明されているメソッドを使用してデータベーススキーマを操作できます。
テーブルまたは列を作成する際は、物理的な型ではなく抽象型を使用することで、マイグレーションを特定のDBMSに依存しないようにする必要があります。yii\db\Schemaクラスは、サポートされている抽象型を表す一連の定数を定義します。これらの定数は、TYPE_<Name>
の形式で命名されます。たとえば、TYPE_PK
は自動増分主キー型を表し、TYPE_STRING
は文字列型を表します。マイグレーションが特定のデータベースに適用されると、抽象型は対応する物理型に変換されます。MySQLの場合、TYPE_PK
はint(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
に変換され、TYPE_STRING
はvarchar(255)
になります。
抽象型を使用する際に、追加の制約を追加できます。上記の例では、NOT NULL
がSchema::TYPE_STRING
に追加され、列がnull
にできないことが指定されています。
情報: 抽象型と物理型のマッピングは、各具体的な
QueryBuilder
クラスの$typeMapプロパティによって指定されます。
バージョン2.0.6以降、新しく導入されたスキーマビルダーを使用できます。これは、列スキーマを定義するより便利な方法を提供します。したがって、上記のマイグレーションは次のように記述できます。
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function up()
{
$this->createTable('news', [
'id' => $this->primaryKey(),
'title' => $this->string()->notNull(),
'content' => $this->text(),
]);
}
public function down()
{
$this->dropTable('news');
}
}
yii\db\SchemaBuilderTraitのAPIドキュメントには、列の種類を定義するためのすべての利用可能なメソッドのリストがあります。
`
php <?php return [
'controllerMap' => [ 'migrate' => [ 'class' => 'yii\console\controllers\MigrateController', 'newFileOwnership' => '1000:1000', # Default WSL user id 'newFileMode' => 0660, ], ],
];
`
バージョン2.0.7以降、マイグレーションコンソールはマイグレーションを作成する便利な方法を提供します。
マイグレーション名が特殊な形式の場合(たとえば、create_xxx_table
またはdrop_xxx_table
)、生成されたマイグレーションファイルには追加のコード(この場合はテーブルの作成/削除に関するコード)が含まれます。以下では、この機能のすべてのバリエーションについて説明します。
yii migrate/create create_post_table
生成します
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey()
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}
テーブルフィールドをすぐに作成するには、--fields
オプションを介して指定します。
yii migrate/create create_post_table --fields="title:string,body:text"
生成します
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(),
'body' => $this->text(),
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}
より多くのフィールドパラメータを指定できます。
yii migrate/create create_post_table --fields="title:string(12):notNull:unique,body:text"
生成します
/**
* Handles the creation for table `post`.
*/
class m150811_220037_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(12)->notNull()->unique(),
'body' => $this->text()
]);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('post');
}
}
注記: 主キーは自動的に追加され、デフォルトでは
id
という名前になります。別の名前を使用する場合は、--fields="name:primaryKey"
のように明示的に指定できます。
2.0.8以降、ジェネレーターはforeignKey
キーワードを使用して外部キーをサポートしています。
yii migrate/create create_post_table --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"
生成します
/**
* Handles the creation for table `post`.
* Has foreign keys to the tables:
*
* - `user`
* - `category`
*/
class m160328_040430_create_post_table extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'author_id' => $this->integer()->notNull(),
'category_id' => $this->integer()->defaultValue(1),
'title' => $this->string(),
'body' => $this->text(),
]);
// creates index for column `author_id`
$this->createIndex(
'idx-post-author_id',
'post',
'author_id'
);
// add foreign key for table `user`
$this->addForeignKey(
'fk-post-author_id',
'post',
'author_id',
'user',
'id',
'CASCADE'
);
// creates index for column `category_id`
$this->createIndex(
'idx-post-category_id',
'post',
'category_id'
);
// add foreign key for table `category`
$this->addForeignKey(
'fk-post-category_id',
'post',
'category_id',
'category',
'id',
'CASCADE'
);
}
/**
* {@inheritdoc}
*/
public function down()
{
// drops foreign key for table `user`
$this->dropForeignKey(
'fk-post-author_id',
'post'
);
// drops index for column `author_id`
$this->dropIndex(
'idx-post-author_id',
'post'
);
// drops foreign key for table `category`
$this->dropForeignKey(
'fk-post-category_id',
'post'
);
// drops index for column `category_id`
$this->dropIndex(
'idx-post-category_id',
'post'
);
$this->dropTable('post');
}
}
列の説明におけるforeignKey
キーワードの位置は、生成されるコードを変更しません。つまり
author_id:integer:notNull:foreignKey(user)
author_id:integer:foreignKey(user):notNull
author_id:foreignKey(user):integer:notNull
すべて同じコードを生成します。
foreignKey
キーワードは、括弧内にパラメータを取ることができます。これは、生成される外部キーの関連テーブルの名前になります。パラメータが渡されない場合、テーブル名は列名から推測されます。
上記の例では、author_id:integer:notNull:foreignKey(user)
は、user
テーブルへの外部キーを持つauthor_id
という名前の列を生成し、category_id:integer:defaultValue(1):foreignKey
はcategory
テーブルへの外部キーを持つcategory_id
という名前の列を生成します。
2.0.11以降、foreignKey
キーワードは、空白で区切られた2番目のパラメータを受け入れます。これは、生成された外部キーの関連列の名前を受け入れます。2番目のパラメータが渡されない場合、列名はテーブルスキーマから取得されます。スキーマが存在しない場合、主キーが設定されていないか、複合キーである場合、デフォルト名はid
が使用されます。
yii migrate/create drop_post_table --fields="title:string(12):notNull:unique,body:text"
生成します
class m150811_220037_drop_post_table extends Migration
{
public function up()
{
$this->dropTable('post');
}
public function down()
{
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(12)->notNull()->unique(),
'body' => $this->text()
]);
}
}
マイグレーション名がadd_xxx_column_to_yyy_table
の形式の場合、ファイルの内容には、必要なaddColumn
とdropColumn
ステートメントが含まれます。
列を追加するには
yii migrate/create add_position_column_to_post_table --fields="position:integer"
生成します
class m150811_220037_add_position_column_to_post_table extends Migration
{
public function up()
{
$this->addColumn('post', 'position', $this->integer());
}
public function down()
{
$this->dropColumn('post', 'position');
}
}
複数の列を次のように指定できます。
yii migrate/create add_xxx_column_yyy_column_to_zzz_table --fields="xxx:integer,yyy:text"
マイグレーション名がdrop_xxx_column_from_yyy_table
の形式の場合、ファイルの内容には、必要なaddColumn
とdropColumn
ステートメントが含まれます。
yii migrate/create drop_position_column_from_post_table --fields="position:integer"
生成します
class m150811_220037_drop_position_column_from_post_table extends Migration
{
public function up()
{
$this->dropColumn('post', 'position');
}
public function down()
{
$this->addColumn('post', 'position', $this->integer());
}
}
マイグレーション名がcreate_junction_table_for_xxx_and_yyy_tables
またはcreate_junction_xxx_and_yyy_tables
の形式の場合、ジャンクションテーブルを作成するために必要なコードが生成されます。
yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:dateTime"
生成します
/**
* Handles the creation for table `post_tag`.
* Has foreign keys to the tables:
*
* - `post`
* - `tag`
*/
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$this->createTable('post_tag', [
'post_id' => $this->integer(),
'tag_id' => $this->integer(),
'created_at' => $this->dateTime(),
'PRIMARY KEY(post_id, tag_id)',
]);
// creates index for column `post_id`
$this->createIndex(
'idx-post_tag-post_id',
'post_tag',
'post_id'
);
// add foreign key for table `post`
$this->addForeignKey(
'fk-post_tag-post_id',
'post_tag',
'post_id',
'post',
'id',
'CASCADE'
);
// creates index for column `tag_id`
$this->createIndex(
'idx-post_tag-tag_id',
'post_tag',
'tag_id'
);
// add foreign key for table `tag`
$this->addForeignKey(
'fk-post_tag-tag_id',
'post_tag',
'tag_id',
'tag',
'id',
'CASCADE'
);
}
/**
* {@inheritdoc}
*/
public function down()
{
// drops foreign key for table `post`
$this->dropForeignKey(
'fk-post_tag-post_id',
'post_tag'
);
// drops index for column `post_id`
$this->dropIndex(
'idx-post_tag-post_id',
'post_tag'
);
// drops foreign key for table `tag`
$this->dropForeignKey(
'fk-post_tag-tag_id',
'post_tag'
);
// drops index for column `tag_id`
$this->dropIndex(
'idx-post_tag-tag_id',
'post_tag'
);
$this->dropTable('post_tag');
}
}
2.0.11以降、ジャンクションテーブルの外部キー列名はテーブルスキーマから取得されます。テーブルがスキーマに定義されていない場合、または主キーが設定されていないか、複合キーである場合、デフォルト名はid
が使用されます。
複雑なDBマイグレーションを実行する際には、各マイグレーションが全体として成功するか失敗するかのいずれかになるようにすることが重要です。これにより、データベースの整合性と一貫性を維持できます。この目標を達成するために、各マイグレーションのDB操作をトランザクションに含めることをお勧めします。
トランザクションマイグレーションを実装するさらに簡単な方法は、マイグレーションコードをsafeUp()
とsafeDown()
メソッドに入れることです。これらの2つのメソッドは、up()
とdown()
とは異なり、暗黙的にトランザクションに含まれます。その結果、これらのメソッド内の操作が失敗すると、それ以前のすべての操作が自動的にロールバックされます。
次の例では、news
テーブルを作成するだけでなく、このテーブルに初期行も挿入します。
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function safeUp()
{
$this->createTable('news', [
'id' => $this->primaryKey(),
'title' => $this->string()->notNull(),
'content' => $this->text(),
]);
$this->insert('news', [
'title' => 'test 1',
'content' => 'content 1',
]);
}
public function safeDown()
{
$this->delete('news', ['id' => 1]);
$this->dropTable('news');
}
}
通常、safeUp()
で複数のDB操作を実行する場合は、safeDown()
でそれらの実行順序を逆にする必要があります。上記の例では、最初にテーブルを作成してからsafeUp()
で行を挿入し、safeDown()
では最初に行を削除してからテーブルを削除します。
注記: すべてのDBMSがトランザクションをサポートするわけではありません。また、一部のDBクエリはトランザクションに含めることができません。例については、暗黙的なコミットを参照してください。この場合、代わりに
up()
とdown()
を実装する必要があります。
基本マイグレーションクラスyii\db\Migrationは、データベースにアクセスして操作するためのメソッドのセットを提供します。これらのメソッドは、yii\db\Commandクラスによって提供されるDAOメソッドと同様に命名されていることがわかります。たとえば、yii\db\Migration::createTable()メソッドを使用すると、yii\db\Command::createTable()と同様に新しいテーブルを作成できます。
yii\db\Migrationによって提供されるメソッドを使用する利点は、yii\db\Commandインスタンスを明示的に作成する必要がなく、各メソッドの実行によって、どのようなデータベース操作が行われ、どのくらいの時間がかかったかがわかる便利なメッセージが自動的に表示されることです。
以下は、これらのデータベースアクセスメソッドのリストです。
情報:yii\db\Migration はデータベースクエリメソッドを提供しません。これは、通常、データベースからのデータ取得に関する追加メッセージを表示する必要がないためです。また、強力なクエリビルダーを使用して複雑なクエリを構築および実行できるためです。マイグレーションでクエリビルダーを使用する方法は次のようになります。
// update status field for all users foreach((new Query)->from('users')->each() as $user) { $this->update('users', ['status' => 1], ['id' => $user['id']]); }
データベースを最新の構造にアップグレードするには、次のコマンドを使用して利用可能なすべての新しいマイグレーションを適用する必要があります。
yii migrate
このコマンドは、これまで適用されていないすべてのマイグレーションを一覧表示します。これらのマイグレーションの適用を確認すると、新しい各マイグレーションクラスのup()
またはsafeUp()
メソッドが、タイムスタンプ値の順に1つずつ実行されます。マイグレーションのいずれかが失敗した場合、コマンドは残りのマイグレーションを適用せずに終了します。
ヒント:サーバーにコマンドラインがない場合は、ウェブシェル拡張機能を試すことができます。
正常に適用された各マイグレーションについて、コマンドはmigration
という名前のデータベーステーブルに行を挿入して、マイグレーションの正常な適用を記録します。これにより、マイグレーションツールは、どのマイグレーションが適用され、どれが適用されていないかを識別できます。
情報:マイグレーションツールは、コマンドのdbオプションで指定されたデータベースに
migration
テーブルを自動的に作成します。デフォルトでは、データベースはdb
アプリケーションコンポーネントによって指定されます。
場合によっては、利用可能なすべてのマイグレーションではなく、1つまたは少数の新しいマイグレーションのみを適用する場合があります。コマンドの実行時に適用するマイグレーションの数を指定することで、これを行うことができます。たとえば、次のコマンドは、次の3つの利用可能なマイグレーションを適用しようとします。
yii migrate 3
特定のマイグレーションにデータベースを移行する必要がある場合は、次のいずれかの形式でmigrate/to
コマンドを使用して明示的に指定することもできます。
yii migrate/to 150101_185401 # using timestamp to specify the migration
yii migrate/to "2015-01-01 18:54:01" # using a string that can be parsed by strtotime()
yii migrate/to m150101_185401_create_news_table # using full name
yii migrate/to 1392853618 # using UNIX timestamp
指定されたマイグレーションより前に適用されていないマイグレーションがある場合、それらはすべて指定されたマイグレーションが適用される前に適用されます。
指定されたマイグレーションが以前に既に適用されている場合、後で適用されたマイグレーションはすべてロールバックされます。
以前に適用された1つまたは複数のマイグレーションをロールバック(元に戻す)するには、次のコマンドを実行します。
yii migrate/down # revert the most recently applied migration
yii migrate/down 3 # revert the most 3 recently applied migrations
注記:すべてのマイグレーションがロールバック可能ではありません。そのようなマイグレーションをロールバックしようとすると、エラーが発生し、ロールバックプロセス全体が停止します。
マイグレーションのやり直しとは、まず指定されたマイグレーションをロールバックしてから、再度適用することを意味します。これは次のように実行できます。
yii migrate/redo # redo the last applied migration
yii migrate/redo 3 # redo the last 3 applied migrations
注記:マイグレーションがロールバック不可能な場合、やり直すことはできません。
Yii 2.0.13以降、データベースからすべてのテーブルと外部キーを削除し、最初からすべてのマイグレーションを適用できます。
yii migrate/fresh # truncate the database and apply all migrations from the beginning
適用されたマイグレーションと適用されていないマイグレーションを一覧表示するには、次のコマンドを使用できます。
yii migrate/history # showing the last 10 applied migrations
yii migrate/history 5 # showing the last 5 applied migrations
yii migrate/history all # showing all applied migrations
yii migrate/new # showing the first 10 new migrations
yii migrate/new 5 # showing the first 5 new migrations
yii migrate/new all # showing all new migrations
マイグレーションを実際に適用またはロールバックする代わりに、データベースが特定のマイグレーションにアップグレードされたことをマークする場合があります。これは、データベースを手動で特定の状態に変更し、その変更のマイグレーションを後で再適用したくない場合によく発生します。これは、次のコマンドを使用して実現できます。
yii migrate/mark 150101_185401 # using timestamp to specify the migration
yii migrate/mark "2015-01-01 18:54:01" # using a string that can be parsed by strtotime()
yii migrate/mark m150101_185401_create_news_table # using full name
yii migrate/mark 1392853618 # using UNIX timestamp
このコマンドは、データベースが指定されたマイグレーションに適用されたことを示すために、特定の行を追加または削除することでmigration
テーブルを変更します。このコマンドでは、マイグレーションは適用またはロールバックされません。
マイグレーションコマンドをカスタマイズするには、いくつかの方法があります。
マイグレーションコマンドには、動作をカスタマイズするために使用できるいくつかのコマンドラインオプションがあります。
interactive
:ブール値(デフォルトはtrue
)、対話モードでマイグレーションを実行するかどうかを指定します。これがtrue
の場合、コマンドが特定のアクションを実行する前に、ユーザーにプロンプトが表示されます。コマンドがバックグラウンドプロセスで使用されている場合は、これをfalse
に設定することをお勧めします。
migrationPath
:文字列|配列(デフォルトは@app/migrations
)、すべてのマイグレーションクラスファイルが格納されているディレクトリを指定します。これは、ディレクトリパスまたはパスエイリアスのいずれかとして指定できます。ディレクトリが存在する必要があることに注意してください。存在しない場合、コマンドはエラーを発生させる可能性があります。バージョン2.0.12以降、複数のソースからマイグレーションを読み込むために配列を指定できます。
migrationTable
:文字列(デフォルトはmigration
)、マイグレーション履歴情報を格納するためのデータベーステーブルの名前を指定します。テーブルが存在しない場合、コマンドによって自動的に作成されます。version varchar(255) primary key, apply_time integer
構造を使用して手動で作成することもできます。
db
:文字列(デフォルトはdb
)、データベースアプリケーションコンポーネントのIDを指定します。これは、このコマンドを使用してマイグレーションされるデータベースを表します。
templateFile
:文字列(デフォルトは@yii/views/migration.php
)、スケルトンマイグレーションクラスファイルの生成に使用されるテンプレートファイルのパスを指定します。これは、ファイルパスまたはパスエイリアスのいずれかとして指定できます。テンプレートファイルはPHPスクリプトであり、$className
という事前定義変数を使用してマイグレーションクラス名を取得できます。
generatorTemplateFiles
:配列(デフォルトは`[
'create_table' => '@yii/views/createTableMigration.php',
'drop_table' => '@yii/views/dropTableMigration.php',
'add_column' => '@yii/views/addColumnMigration.php',
'drop_column' => '@yii/views/dropColumnMigration.php',
'create_junction' => '@yii/views/createTableMigration.php'
]`)、マイグレーションコードの生成のためのテンプレートファイルを指定します。「マイグレーションの生成」で詳細を参照してください。
fields
:マイグレーションコードの作成に使用されるカラム定義文字列の配列。デフォルトは[]
です。各定義の形式はCOLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR
です。たとえば、--fields=name:string(12):notNull
は、NULLではないサイズ12の文字列カラムを生成します。
次の例は、これらのオプションの使用方法を示しています。
たとえば、マイグレーションファイルがモジュールのmigrations
ディレクトリ内にあるforum
モジュールをマイグレーションする場合は、次のコマンドを使用できます。
# migrate the migrations in a forum module non-interactively
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0
マイグレーションコマンドを実行するたびに同じオプション値を入力する代わりに、以下に示すようにアプリケーション構成ですべて一度に設定できます。
return [
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationTable' => 'backend_migration',
],
],
];
上記の構成では、マイグレーションコマンドを実行するたびに、backend_migration
テーブルを使用してマイグレーション履歴が記録されます。migrationTable
コマンドラインオプションで指定する必要がなくなります。
2.0.10以降、マイグレーションクラスに名前空間を使用できます。migrationNamespacesを介してマイグレーション名前空間のリストを指定できます。マイグレーションクラスの名前空間の使用により、マイグレーションの複数のソースロケーションを使用できます。たとえば
return [
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationPath' => null, // disable non-namespaced migrations if app\migrations is listed below
'migrationNamespaces' => [
'app\migrations', // Common migrations for the whole application
'module\migrations', // Migrations for the specific project's module
'some\extension\migrations', // Migrations for the specific extension
],
],
],
];
注記:異なる名前空間から適用されたマイグレーションは、**単一**のマイグレーション履歴を作成します。たとえば、特定の名前空間からのマイグレーションのみを適用またはロールバックできない場合があります。
名前空間付きマイグレーションを操作する(新規作成、ロールバックなど)際には、マイグレーション名の前に完全な名前空間を指定する必要があります。バックスラッシュ(\
)記号は通常、シェルでは特殊文字と見なされるため、シェルエラーや不正な動作を避けるために適切にエスケープする必要があります。たとえば
yii migrate/create app\\migrations\\CreateUserTable
注記:migrationPathを介して指定されたマイグレーションには名前空間を含めることができず、名前空間付きマイグレーションはyii\console\controllers\MigrateController::$migrationNamespacesプロパティを介してのみ適用できます。
バージョン2.0.12以降、migrationPathプロパティは、名前空間のないマイグレーションを含む複数のディレクトリを指定するためにも配列を受け入れます。これは主に、異なる場所からマイグレーションを使用する既存のプロジェクトで使用するために追加されました。これらのマイグレーションは主に、他の開発者によって開発されたYii拡張機能など、外部ソースから提供されるものであり、新しいアプローチの使用を開始する際に名前空間を使用するように簡単に変更することはできません。
名前空間付きマイグレーションは、M<YYMMDDHHMMSS><Name>
という「CamelCase」命名パターンに従います(たとえば、M190720100234CreateUserTable
)。このようなマイグレーションを生成する際には、テーブル名が「CamelCase」形式から「アンダースコア」形式に変換されることに注意してください。たとえば
yii migrate/create app\\migrations\\DropGreenHotelTable
は、app\migrations
名前空間内にgreen_hotel
テーブルを削除するマイグレーションを生成し、
yii migrate/create app\\migrations\\CreateBANANATable
は、app\migrations
名前空間内にb_a_n_a_n_a
テーブルを作成するマイグレーションを生成します。
テーブル名が混合大文字小文字(studentsExam
など)の場合は、名前の前にアンダースコアを付ける必要があります。
yii migrate/create app\\migrations\\Create_studentsExamTable
これにより、app\migrations
名前空間内にstudentsExam
テーブルを作成するマイグレーションが生成されます。
プロジェクトのすべてのマイグレーションに単一のマイグレーション履歴を使用することが望ましくない場合があります。たとえば、「ブログ」拡張機能をインストールする場合、完全に分離された機能が含まれており、メインプロジェクトの機能専用のマイグレーションに影響を与えない独自のマイグレーションが含まれている場合があります。
複数のマイグレーションを互いに完全に分離して適用および追跡する場合は、異なる名前空間とマイグレーション履歴テーブルを使用する複数のマイグレーションコマンドを設定できます。
return [
'controllerMap' => [
// Common migrations for the whole application
'migrate-app' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationNamespaces' => ['app\migrations'],
'migrationTable' => 'migration_app',
'migrationPath' => null,
],
// Migrations for the specific project's module
'migrate-module' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationNamespaces' => ['module\migrations'],
'migrationTable' => 'migration_module',
'migrationPath' => null,
],
// Migrations for the specific extension
'migrate-rbac' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationPath' => '@yii/rbac/migrations',
'migrationTable' => 'migration_rbac',
],
],
];
データベースを同期するには、1つのコマンドではなく、複数のコマンドを実行する必要があることに注意してください。
yii migrate-app
yii migrate-module
yii migrate-rbac
デフォルトでは、マイグレーションはdb
アプリケーションコンポーネントで指定された同じデータベースに適用されます。異なるデータベースに適用する場合は、以下に示すようにdb
コマンドラインオプションを指定できます。
yii migrate --db=db2
上記のコマンドは、db2
データベースにマイグレーションを適用します。
マイグレーションの一部を1つのデータベースに適用し、他のマイグレーションを別のデータベースに適用する場合があります。この目的を達成するために、マイグレーションクラスを実装する際には、マイグレーションが使用するDBコンポーネントIDを明示的に指定する必要があります。以下のように。
<?php
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function init()
{
$this->db = 'db2';
parent::init();
}
}
上記マイグレーションは、db
コマンドラインオプションを介して異なるデータベースを指定した場合でも、db2
に適用されます。マイグレーション履歴は、db
コマンドラインオプションで指定されたデータベースに引き続き記録されます。
同じデータベースを使用するマイグレーションが複数ある場合は、上記のinit()
コードを含む基本マイグレーションクラスを作成することをお勧めします。その後、各マイグレーションクラスはこの基本クラスから拡張できます。
ヒント: db プロパティを設定する以外にも、マイグレーションクラスに新しいデータベース接続を作成することで、異なるデータベースを操作できます。その後、これらの接続を使用してDAOメソッド を使用し、異なるデータベースを操作します。
複数のデータベースをマイグレートするもう一つの方法は、異なるデータベースのマイグレーションを異なるマイグレーションパスに保持することです。その後、次のような個別のコマンドでこれらのデータベースをマイグレートできます。
yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...
最初のコマンドは、@app/migrations/db1
内のマイグレーションをdb1
データベースに適用し、2番目のコマンドは、@app/migrations/db2
内のマイグレーションをdb2
に適用するなどとなります。
タイプミスを発見した、またはこのページの改善が必要だと考えますか?
Githubで編集する !
マイグレーションでテーブルオプション(例:データベースエンジンタイプ(MyISAM、InnoDBなど))を追加したい場合は、これを使用します。
InnoDBなどを使用します。
public function safeUp() { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; $this->createTable('news', [ 'id' => $this->primaryKey(), 'title' => $this->string()->notNull(), 'content' => $this->text(), ], $tableOptions); }
DDLマイグレーションをリバースエンジニアリングするには、[https://yii.dokyumento.jp/extension/yii2-migration-creator](Migration Creator And Updater) を参照してください。これは素晴らしく、よく保守されている拡張機能であり、スキーマの更新をスクリプトに簡単に変換するために非常に役立ちます。
また、DMLリバースエンジニアリングスクリプトを探していましたが、見つからなかったので自分で作成しました。作成する過程で、Yiiフレームワークの強力さを実感し、数行のコードでこれを実現できました。下記をご覧ください。
<?php namespace console\controllers; use yii\console\Controller; use frontend\models\Child; use frontend\models\Parent; /** * Export Template and Reference Data */ class ExportController extends Controller { /** * Export Reference given the id */ public function actionReference($parent_id) { $parent_id = (integer) $parent_id; // Generate Deletes $this->genDelete('child', 'parent_id', $parent_id); $this->genDelete('parent', 'id', $parent_id); // Generate Inserts $this->genInsert(Parent::find()->where(['id' => $parent_id])->one()); $this->genInsert(Child::find()->where(['parent_id' => $parent_id])->all()); } /** * Export All Reference */ public function actionReferenceAll() { // Generate Deletes echo $this->genDeleteAll('child'); echo $this->genDeleteAll('parent'); // Generate Inserts $this->genInsert(Parent::find()->orderBy(['id' => SORT_ASC])->all()); $this->genInsert(Child::find()->orderBy(['parent_id' => SORT_ASC])->all()); } /** * Checks if Object or Object Array and calls Insert for each Model */ protected function genInsert($models) { if (is_array($models)) { foreach ($models as $model) { $this->genInsert1($model); } } else { $this->genInsert1($models); } } /** * Formats the insert for a given Model */ protected function genInsert1($model) { $output = preg_replace("/^/m", " ", '$this->' . "insert('" . $model->tableName() . "'," . PHP_EOL . ' ' . var_export($model->attributes, true) . ");") . PHP_EOL; echo $output; } /** * Generates/Formats the Delete statement given Table, Column and Column Value (where condition) */ protected function genDelete($tableName, $columnName, $columnValue) { $output = preg_replace("/^/m", " ", '$this->' . "delete('" . $tableName . "', '" . $columnName . " = :vcolumn', [':vcolumn' => " . $columnValue . "]);") . PHP_EOL; echo $output; } /** * Generates/Formats the Delete statement to delete all rows for a Table */ protected function genDeleteAll($tableName) { $output = preg_replace("/^/m", " ", '$this->' . "delete('" . $tableName . "');") . PHP_EOL; echo $output; } }
php yii migrate
php yii help migrate
コメントするにはサインアップ または ログインしてください。