9 フォロワー

データベースマイグレーション

データベース駆動型アプリケーションの開発と保守において、使用されているデータベースの構造はソースコードと同様に進化します。例えば、アプリケーションの開発中に新しいテーブルが必要になる場合や、アプリケーションを本番環境にデプロイした後、クエリの性能を向上させるためにインデックスを作成する必要があることが判明する場合などがあります。データベース構造の変更は多くの場合、ソースコードの変更も必要とするため、Yiiは、ソースコードと共にバージョン管理されるデータベースマイグレーションという形で、データベースの変更を追跡できる、いわゆるデータベースマイグレーション機能をサポートしています。

次の手順は、開発中にチームがデータベースマイグレーションをどのように使用できるかを示しています。

  1. Timは新しいマイグレーションを作成します(例:新しいテーブルの作成、カラム定義の変更など)。
  2. Timは新しいマイグレーションをソースコントロールシステム(例:Git、Mercurial)にコミットします。
  3. Dougはソースコントロールシステムからリポジトリを更新し、新しいマイグレーションを受け取ります。
  4. Dougは、新しいマイグレーションをローカルの開発データベースに適用し、Timが行った変更を反映するようにデータベースを同期します。

そして、次の手順は、データベースマイグレーションを使用して新しいリリースを本番環境にデプロイする方法を示しています。

  1. Scottは、いくつかの新しいデータベースマイグレーションを含むプロジェクトリポジトリにリリースタグを作成します。
  2. Scottは、本番サーバーのソースコードをリリースタグに更新します。
  3. Scottは、蓄積されたデータベースマイグレーションを本番データベースに適用します。

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_PKint(11) NOT NULL AUTO_INCREMENT PRIMARY KEYに変換され、TYPE_STRINGvarchar(255)になります。

抽象型を使用する際に、追加の制約を追加できます。上記の例では、NOT NULLSchema::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):foreignKeycategoryテーブルへの外部キーを持つ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の形式の場合、ファイルの内容には、必要なaddColumndropColumnステートメントが含まれます。

列を追加するには

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の形式の場合、ファイルの内容には、必要なaddColumndropColumnステートメントが含まれます。

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で編集する !