Database migration | database | Yii Chinese document 2.0.x

Database migration

When developing and maintaining a database driven application, the structure of the database will evolve like code. For example, in the process of developing an application, a new table will be added and must be added; After the application is deployed to the production environment, it is necessary to establish an index to improve the performance of query and so on. Because the source code often needs to be changed when a database structure changes, Yii provides a database migration function, which can record the changes of the database so that the database and the source code can be version controlled together.

The following steps show us how the database migration tool is used by the development team:

  1. Tim creates a new migration object (for example, creating a new table, changing the definition of fields, etc.).
  2. Tim submits the new migration object to the code management system (for example, Git, Mercurial).
  3. Doug updates the version from the code management system and obtains the new migration object.
  4. Doug submits the migration object to the local development database. In this way, Doug synchronizes the changes made by Tim.

The following steps show us how to release a new version with database migration to the production environment:

  1. Scott created a release label for a version of the project that included database migration.
  2. Scott updates the source code of the release label to the server of the production environment.
  3. Scott submits all incremental database migrations to the production environment database.

Yii provides a complete set of migration command line tools, through which you can:

  • Create a new migration;
  • Submit migration;
  • Restore migration;
  • Resubmit the migration;
  • Show migration history and status.

All of these tools can be operated through the yii migrate command. In this chapter, we will introduce in detail how to use these tools to complete a variety of tasks. You can also get the specific usage of each tool through the yii help migrate command.

Tip: migration does not only work on database tables, but also adjusts existing data to adapt to new forms, create RBAC hierarchies, or clear the cache.

Note: when you use migration to manipulate data, you will find that Activity record Class is helpful because some logic is already implemented there. However, don't forget that program logic changes at any time compared to the code in the migrated class that is inherently constant. Therefore, when you use the activity record class in the migration, the change of logic in the activity record layer may accidentally interrupt the existing migration. For this reason, the migrated code should remain independent of other program logic, such as the activity record class.

Create migration

Use the following command to create a new migration:

yii migrate/create <name>

The required parameter name is used to give a brief description of the new migration. For example, if the migration is used to create a table called news, you can use create_news_table and run the following command:

yii migrate/create create_news_table

Note: because the name parameter will be used to generate part of the migrated class name, the parameter should only contain letters, numbers and underscores.

The above command will create a new one named m150101 in the @ app/migrations directory_ 185401_ create_ news_ table. PHP class file for PHP. Their m150101 file contains the following code for migration_ 185401_ create_ news_ Table with code framework:

<?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()
    {
    }
    */
}

Each database migration is defined as a PHP class inherited from [[yii\db\Migration]]. The name of the class is based on M < yymmdd_ HHMMSS>_< The format of name > is automatically generated, where

  • <YYMMDD_ Hhmmss > refers to the UTC time when the create migration command is executed.
  • < name > is the same as the value of the name parameter when you execute the command.

In the migration class, you should write code to change the database structure in the up() method. You may also need to write code in the down() method to restore the changes made by the up() method. When you upgrade the database through migration, the up() method will be called, otherwise, the down() method will be called. The following code shows how to create a news table by migrating classes:

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends \yii\db\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');
    }

}

Note: not all migrations are recoverable. For example, if the up() method deletes a row of data in the table, it will not be able to recover the data through the down() method. Sometimes, you may just be too lazy to execute the down() method, because it is not so common in restoring database migration. In this case, you should return false in the down() method to indicate that the migration is unrecoverable.

The base class [[yii\db\Migration]] of migration connects to the database through the [[yii\db\Migration::db|db]] attribute. You can pass Operational database schema The methods described in the chapter operate the database schema.

When you create a table or a field, you should use abstract types instead of entity types, so that your migration objects can be extracted from a specific DBMS. The [[yii\db\Schema]] class defines a set of available abstract type constants. The format of these constants is type_< Name>. For example, TYPE_PK refers to the self incrementing primary key type; TYPE_STRING refers to a string type. When the migration object is submitted to a specific database, these abstract types will be converted to the corresponding entity types. Take MySQL as an example, TYPE_PK will become int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, while TYPE_STRING becomes varchar(255).

When using abstract types, you can add additional constraints. In the above example, NOT NULL is added to Schema::TYPE_STRING to specify that this field cannot be empty.

Tip: the mapping relationship between abstract types and entity types is specified by the [[yii\db\QueryBuilder::$typeMap|$typeMap]] attribute in each specific QueryBuilder class.

Starting with version 2.0.6, you can use a new schema builder that provides a more convenient way to define field schemas. In this way, the above migration can be written as follows:

<?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');
    }
}

All methods used to define field types can be found in the API document of [[yii\db\SchemaBuilderTrait]].

Generate migration

Starting from version 2.0.7, the migration terminal provides a convenient method to create migration.

If the name of the migrated object follows a specific format, such as create_xxx or drop_xxx, the generated migration code will contain additional code for creating / deleting tables. All variants of this feature will be described below.

Create table

yii migrate/create create_post

generate

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey()
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('post');
    }
}

Using the -- fields option to specify field parameters, you can create fields immediately.

yii migrate/create create_post --fields="title:string,body:text"

generate

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post 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');
    }
}

You can specify more field parameters.

yii migrate/create create_post --fields="title:string(12):notNull:unique,body:text"

generate

/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post 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');
    }
}

Note: the primary key will be automatically added, and the default name is id. If you want to use another name, you can use -- fields="name:primaryKey" to specify the name.

Foreign key

Starting with version 2.0.8, the generator supports foreign keys by using the foreignKey keyword.

yii migrate/create create_post --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"

generate

/**
 * Handles the creation for table `post`.
 * Has foreign keys to the tables:
 *
 * - `user`
 * - `category`
 */
class m160328_040430_create_post 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');
    }
}

The position of the foreignKey keyword in the field description does not affect the generated code. That means:

  • author_idnotNull:foreignKey(user)
  • author_idforeignKey(user):notNull
  • author_id:foreignKey(user)notNull

The above will generate the same code.

foreignKey keyword can receive a parameter in the middle of parentheses, which will become the name of the association table required to generate foreign keys. If no parameters are passed in, the table name will be generated based on the field name.

In the above example, author_idnotNull:foreignKey(user) will generate a foreign key with the associated user table named author_ Field of ID, category_iddefaultValue(1):foreignKey will generate a foreign key with an associated category table named category_ Field of ID.

Starting from version 2.0.11, foreignKey receives the second parameter, separated from the first parameter with a space. This parameter represents the name of the field associated with the generated foreign key. If the second parameter is not passed in, the field name will be obtained from the table schema. If the schema does not exist, or the primary key is not set, or it is a federated primary key, the field will use id as the default name.

Delete table

yii migrate/create drop_post --fields="title:string(12):notNull:unique,body:text"

generate

class m150811_220037_drop_post 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 field

If the name of the migration follows add_ xxx_ to_ In the format of YYY, the generated class file will contain the necessary addColumn and dropColumn.

Add field:

yii migrate/create add_position_to_post --fields="position:integer"

generate

class m150811_220037_add_position_to_post extends Migration
{
    public function up()
    {
        $this->addColumn('post', 'position', $this->integer());
    }

    public function down()
    {
        $this->dropColumn('post', 'position');
    }
}

You can specify multiple fields as follows:

yii migrate/create add_xxx_column_yyy_column_to_zzz_table --fields="xxx:integer,yyy:text"

Delete field

If the name of the migration follows drop_ xxx_ from_ In the format of YYY, the generated class file will contain the necessary addColumn and dropColumn.

yii migrate/create drop_position_from_post --fields="position:integer"

generate

class m150811_220037_drop_position_from_post extends Migration
{
    public function up()
    {
        $this->dropColumn('post', 'position');
    }

    public function down()
    {
        $this->addColumn('post', 'position', $this->integer());
    }
}

Add connection table

If the name of the migration follows create_ junction_ xxx_ and_ In the format of YYY, the necessary code to create the join table will be generated.

yii migrate/create create_junction_post_and_tag --fields="created_at:dateTime"

generate

/**
 * Handles the creation for table `post_tag`.
 * Has foreign keys to the tables:
 *
 * - `post`
 * - `tag`
 */
class m160328_041642_create_junction_post_and_tag 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');
    }
}

Starting with version 2.0.11, the foreign key field name of the join table will be obtained from the table schema. If the schema does not exist, or the primary key is not set, or it is a federated primary key, the field will use id as the default name.

Transaction migration

When it is necessary to implement complex database migration, it becomes very important to determine whether the execution of each migration is successful or failed, because it will affect the integrity and consistency of the database. In order to achieve this goal, we recommend that you encapsulate the database operations in each migration into one transaction Inside.

A simpler way to implement transaction migration is to put the migrated code into safeUp() and safeDown() methods. They differ from up() and down() in that they are implicitly encapsulated into transactions. In this way, as long as any of these methods fails, all previous operations will be rolled back automatically.

In the following example, in addition to creating the news table, we also inserted a row of initialization data into the table.

use yii\db\Schema;
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');
    }
}

It should be noted that when you perform multiple database operations in safeUp(), you should reverse their execution order in safeDown() method. In the above example, we first create a table in the safeUp() method, and then insert a piece of data; In the safeDown() method, we first delete the row of data, and then delete the table.

Note: not all databases support transactions. Some database queries cannot be put into transactions. stay implicit commit There are relevant examples to refer to in this chapter. If this happens, you should use the up() and down() methods instead.

Method of accessing database

The migrated base class [[yii\db\Migration]] provides a complete set of methods to access and operate the database. You may find the naming of these methods and the methods provided by the [[yii\db\Command]] class DAO method Very similar. For example, as like as two peas, [[yii\db\Migration::createTable()], the method can create a new table, which is exactly the same as [[yii\db\Command::createTable()].

The advantage of using the method provided by [[yii\db\Migration]] is that you don't need to explicitly create [[yii\db\Command]] instances, and when executing each method, some useful information will be displayed to tell us whether the database operations have been completed and how long they took to complete these operations.

The following is a list of all these database access methods:

  • [[yii\db\Migration::execute()|execute()]]: execute an SQL statement
  • [[yii\db\Migration::insert()|insert()]]: insert single row data
  • [[yii\db\Migration::batchInsert()|batchInsert()]]: insert multiple rows of data
  • [[yii\db\Migration::update()|update()]]: update data
  • [[yii\db\Migration::delete()|delete()]]: delete data
  • [[yii\db\Migration::createTable()|createTable()]]: create table
  • [[yii\db\Migration::renameTable()|renameTable()]]: rename table name
  • [[yii\db\Migration::dropTable()|dropTable()]]: delete a table
  • [[yii\db\Migration::truncateTable()|truncateTable()]]: clear all data in the table
  • [[yii\db\Migration::addColumn()|addColumn()]]: add a field
  • [[yii\db\Migration::renameColumn()|renameColumn()]]: Rename field name
  • [[yii\db\Migration::dropColumn()|dropColumn()]]: delete a field
  • [[yii\db\Migration::alterColumn()|alterColumn()]]: modify field
  • [[yii\db\Migration::addPrimaryKey()|addPrimaryKey()]]: add a primary key
  • [[yii\db\Migration::dropPrimaryKey()|dropPrimaryKey()]]: delete a primary key
  • [[yii\db\Migration::addForeignKey()|addForeignKey()]]: add a foreign key
  • [[yii\db\Migration::dropForeignKey()|dropForeignKey()]]: delete a foreign key
  • [[yii\db\Migration::createIndex()|createIndex()]]: create an index
  • [[yii\db\Migration::dropIndex()|dropIndex()]]: delete an index
  • [[yii\db\Migration::addCommentOnColumn()|addCommentOnColumn()]]: add a comment for the field
  • [[yii\db\Migration::dropCommentFromColumn()|dropCommentFromColumn()]]: delete the comment of the field
  • [[yii\db\Migration::addCommentOnTable()|addCommentOnTable()]]: add comments to the table
  • [[yii\db\Migration::dropCommentFromTable()|dropCommentFromTable()]]: delete comments on the table

Tip: [[yii\db\Migration]] does not provide a query method for the database. This is because usually you don't need to go to the database to find out the data line by line and then display it. Another reason is that you can use powerful Query Builder To build and query.
You can use the query builder in the migration like this:

// Update the status field for all users
foreach((new Query)->from('users')->each() as $user) {
    $this->update('users', ['status' => 1], ['id' => $user['id']]);
}

Submit migration

In order to upgrade the database to the latest structure, you should submit all new migrations using the following command:

yii migrate

This command lists all the migrations that have not been committed so far. If you decide that you need to submit these migrations, it will run the up() or safeUp() methods in each new migration class one by one in the order of time stamps in the class name. If any of the migrations fails to commit, this command will exit and stop the remaining migrations that have not yet been executed.

Tip: if your server doesn't have a command line, you can try web shell This extension.

For each successfully submitted migration, this command will insert a record containing the successful migration submitted by the application in a database table called migration. This record will help the migration tool judge which migrations have been submitted and which have not been submitted.

Info: the migration tool will automatically create a migration table in the database specified in the [[yii\console\controllers\MigrateController::db|db]] option of the command. By default, DB application component designated.

Sometimes, you may only need to submit one or a few migrations. You can use this command to specify the number of migrations to be executed instead of all available migrations. For example, the following command will attempt to commit the first three available migrations:

yii migrate 3

You can also specify a specific migration. Use the migrate/to command to specify which migration the database should submit according to the following format:

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() uses 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

If there are uncommitted migrations before the specified migration to be submitted, these uncommitted migrations will be submitted before the specified migration is executed.

If the migration specified to be submitted has been submitted before, those subsequent migrations will be restored.

Restore migration

You can use the following command to restore the migration in which one or more comments have been submitted:

yii migrate/down     # revert the most recently applied migration
yii migrate/down 3   # revert the most 3 recently applied migrations

Note: not all migrations can be restored. Attempting to restore such migrations may result in an error or even the termination of all restore processes.

Redo migration

Redo migration means restoring the specified migration first and then submitting it again. As follows:

yii migrate/redo        # Redo the last committed migration
yii migrate/redo 3      # Redo the last three committed migrations

Note: if a migration cannot be restored, you will not be able to redo it.

Refresh migration

Starting with version 2.0.13, you can delete all tables and foreign keys from the database and resubmit all migrations from scratch.

yii migrate/fresh       # Empty the database and apply all migrations from scratch.

List migrations

You can use the following command to list those migrations that have been submitted or have not yet been submitted:

yii migrate/history     # Displays the last 10 committed migrations
yii migrate/history 5   # Displays the last 5 committed migrations
yii migrate/history all # Displays all migrations that have been committed

yii migrate/new         # Displays the top 10 uncommitted migrations
yii migrate/new 5       # Displays the first five uncommitted migrations
yii migrate/new all     # Displays all migrations that have not yet been committed

Modify migration history

Sometimes you may need to simply mark that your database has been upgraded to a specific migration instead of actually committing or restoring the migration. This often happens when you manually change a specific state of the database without the corresponding migration being resubmitted. Then you can use the following commands to achieve your goal:

yii migrate/mark 150101_185401                      # Use timestamp to specify migration
yii migrate/mark "2015-01-01 18:54:01"              # Use a string that can be parsed by strtotime()
yii migrate/mark m150101_185401_create_news_table   # Use full name
yii migrate/mark 1392853618                         # Use UNIX timestamp

This command will add or delete some rows of data in the migration table to indicate that the database has been submitted to a specified migration. No migration will be committed or restored during the execution of this command.

Custom migration

There are many ways to customize migration commands.

Use command line options

The migration command comes with several command line options that you can use to customize its behavior:

  • Interactive: boolean (the default value is true), which specifies whether to run the migration in interactive mode. When set to true, the user will be prompted before the command performs some operations. If you want to execute this command in the background, you should set it to false.

  • migrationPath: string|array (the default value is @ app/migrations), which specifies the directory where all migration class files are stored. This option can be the path to a directory or path alias . It should be noted that the specified directory must exist, otherwise an error will be triggered. Starting with version 2.0.12, an array can be used to specify that migration class files are read from multiple sources.

  • migrationTable: string (the default value is migration), which specifies the name of the database table used to store migration history information. If this table does not exist, the migration command will automatically create this table. Of course, you can also use such a field structure: version varchar(255) primary key, apply_time integer to manually create this table.

  • db: string (the default value is db), specifying the database application component ID of the. It refers to the database that will be migrated by this command.

  • templateFile: string (the default value is @ yii/views/migration.php), which specifies the template file path of the production migration framework code class file. This option can be specified using either a file path or a path alias To specify. The template file is a PHP script that can use the predefined variable $className to get the name of the migration class.

  • generatorTemplateFiles: array (defaults to [ '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/createJunctionMigration.php' ]), Specify the template file that generates the migration code. View“ Generating Migrations "For more details.

  • fields: an array of multiple field definition strings used to create migration code. The default is []. The format of the field definition is COLUMN_NAMECOLUMN_DECORATOR. For example, -- fields=name:string(12):notNull will create a non empty, string type field with a length of 12.

The following example shows us how to use these options:

For example, if we need to migrate a forum module and the migration file is placed in the migrations directory under the module, we can use the following command:

# Migrate in non interactive mode in forum module
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0

Global configuration command

In order to avoid repeatedly entering some of the same parameters when running the migration command, you can choose to conduct global configuration in the application configuration, once and for all:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];

Configure as shown above. Each time you run the migration command, the backend_ The migration table will be used to record the migration history. You no longer need to specify this history table through the migrationTable command line parameter.

Migration using namespaces

Since version 2.0.10, you can use namespaces for migrated classes. You can specify the namespace to be used in migration through [[yii\console\controllers\MigrateController::migrationNamespaces|migrationNamespaces]]. Using namespaces will allow you to migrate from multiple source locations. For example:

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
            ],
        ],
    ],
];

Note: the migration submitted from different namespaces will create a single migration history. For example, you can't submit or restore the migration only from a specific namespace.

When you are operating the migration using namespace: such as creating migration, restoring migration, etc., you should indicate the complete namespace before the migration name. Note that the backslash (\) will be regarded as a special character in the shell. You should encode the backslash to avoid shell error or incorrect results. For example:

yii migrate/create 'app\\migrations\\createUserTable'

Note: migrations declared through [[yii\console\controllers\MigrateController::migrationPath|migrationPath]] cannot contain namespaces. Migrations using namespaces can only be submitted through the properties of [[yii\console\controllers\MigrateController::migrationNamespaces]].

Starting from version 2.0.12, the [[yii\console\controllers\MigrateController::migrationPath|migrationPath]] property also receives an array as a parameter, which indicates multiple migrated directories that do not use namespaces. This parameter is mainly used for existing projects that have been migrated from multiple locations. These migrations mainly come from external resources, such as Yii extensions developed by other developers. When using new methods, it is difficult to change these migrations to use namespaces.

Separate migration

Sometimes we don't want all migrations of the whole project to be recorded in the same migration history. For example, you may have installed the 'blog' extension, which has its own independent functions and migration, and will not affect other extensions for the main functions of the project.

If you want to submit and track multiple migrations completely separately, you can configure multiple migration commands using different namespaces and history tables at the same time:

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',
        ],
    ],
];

Note that to synchronize the database, you now need to run multiple commands instead of one:

yii migrate-app
yii migrate-module
yii migrate-rbac

Migrate multiple databases

By default, the migration will be submitted to db application component Defined in the same database. If you need to submit to different databases, you can specify the db command line option as follows,

yii migrate --db=db2

The above command will commit the migration to the db2 database.

Sometimes you need to commit some to one database and others to another database. To achieve this goal, you should specify the ID of the database component to be used when implementing a migration class, as shown below:

<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function init()
    {
        $this->db = 'db2';
        parent::init();
    }
}

Even if you specify a different database using the db command line option, the above migration will be submitted to db2. It should be noted that the migration history information will still be recorded in the database specified by the db command line option at this time.

If multiple migrations use the same database, it is recommended that you create a migration base class containing the above init() code. Then each migration class can inherit the base class.

Tip: in addition to setting in the [[yii\db\Migration::db|db]] parameter, you can also operate different databases by creating a new database connection in the migration class. Then use these connections DAO method To operate different databases.

Another strategy that allows you to migrate multiple databases is to store the migration in different directories, and then you can migrate different databases through the following commands:

yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...

The first command will submit the migration under @ app/migrations/db1 directory to the db1 database, the second command will submit the migration under @ app/migrations/db2 to the db2 database, and so on.

💖 Those who like this document are welcome to like, collect, leave a message or forward it. Thank you for your support! Author email: zhuzixian520@126.com

This article was first published in LearnKu.com On the website.

Added by impulse() on Sun, 06 Feb 2022 08:58:37 +0200