Home  >  Article  >  php教程  >  yii2.0 database migration tutorial

yii2.0 database migration tutorial

高洛峰
高洛峰Original
2016-12-20 16:30:321109browse

This article describes the method of yii2.0 database migration. Share it with everyone for your reference, the details are as follows:

Create a migration

Use the following command to create a new migration:

yii migrate/create <name>

The role of the required parameter name is to give a brief description of the new migration. For example, if this migration is used to add fields to the same table in multiple databases (assuming each database has a news table), then you can use the name addColumn_news (the name is customized) and run the following command:

yii migrate/create addColumn_news

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

The above command will create a new PHP class file named m150101_185401_addColumn_news.php in the @app/migrations directory. This file contains the following code, which is used to declare a migration class m150101_185401_addColumn_news, with a code skeleton:

<?php
use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_addColumn_news extends Migration
{
//createDbs 该方法是获取数据库对象返回
private function createDbs(){
  $dbs = [];
  $dbs_info =\Yii::$app->params[&#39;db&#39;];
  foreach($dbs_info as $k=>$v){
    $dbs[$k] = \Yii::createObject($v);
  }
  return $dbs;
}
//up() 该方法是往不同的数据库的news表添加 name,nickname,age,sex,site_id等字段
public function up()
{
  $dbs = $this->createDbs();
  foreach($dbs as $v){   //《------遍历讲字段同时添加到不同的数据库中
    $this->db=$v;
    $this->addColumn(&#39;{{%news}}&#39;,&#39;name&#39;,&#39;varchar(20)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;nickname&#39;,&#39;varchar(20)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;age&#39;,&#39;int(3)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;sex&#39;,&#39;int(1)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;site_id&#39;,&#39;int(5)&#39;);
  }
}
//down()  该方法与up()方法相反,是删除字段的意思
public function down()
{
  $dbs = $this->createDbs();
  foreach($dbs as $v){
    $this->db=$v;
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;name&#39;,&#39;varchar(20)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;nickname&#39;,&#39;varchar(20)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;age&#39;,&#39;int(3)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;sex&#39;,&#39;int(1)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;site_id&#39;,&#39;int(5)&#39;);
  }
}
}

Each database migration will be defined as a PHP class inherited from yiidbMigration. The name of the class is automatically generated in the format of m3f41681be24f336d7c374e431294cbbd_af0c92e9f9d1400e4fba6230747949fe, where

3f41681be24f336d7c374e431294cbbd refers to the UTC time when the create migration command is executed.

af0c92e9f9d1400e4fba6230747949fe is the same as the name parameter value when you execute the command.

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

use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_create_news_table extends \yii\db\Migration
{
  public function up()
  {
    $this->createTable(&#39;news&#39;, [
      &#39;id&#39; => Schema::TYPE_PK,
      &#39;title&#39; => Schema::TYPE_STRING . &#39; NOT NULL&#39;,
      &#39;content&#39; => Schema::TYPE_TEXT,
    ]);
  }
  public function down()
  {
    $this->dropTable(&#39;news&#39;);
  }
}

Note: Not all migrations are reversible. For example, if the up() method deletes a row of data in the table, this data cannot be restored through the down() method. Sometimes, you might just be too lazy to execute the down() method because it's not that versatile for reverting database migrations. In this case, you should return false in the down() method to indicate that the migration is irreversible.

Methods to access the database

The migration base class yiidbMigration provides a complete set of methods to access and operate the database. You may find that the naming of these methods is similar to the DAO methods provided by the yiidbCommand class. For example, the yiidbMigration::createTable() method can create a new table, which has the same function as yiidbCommand::createTable().

The advantage of using the methods provided by yiidbMigration is that you no longer need to explicitly create yiidbCommand instances, and some useful information will be displayed when executing each method to tell us whether the database operations have been completed and what they are. How long it took to complete these operations, etc.

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

yiidbMigration::execute(): Execute a SQL statement
yiidbMigration::insert(): Insert a single row of data
yiidbMigration::batchInsert(): Insert multiple rows of data
yiidbMigration ::update(): Update data
yiidbMigration::delete(): Delete data
yiidbMigration::createTable(): Create table
yiidbMigration::renameTable(): Rename table name
yiidbMigration::dropTable(): Delete one Table
yiidbMigration::truncateTable(): Clear all data in the table
yiidbMigration::addColumn(): Add a field
yiidbMigration::renameColumn(): Rename a field name
yiidbMigration::dropColumn(): Delete a field
yiidbMigration::alterColumn(): Modify a field
yiidbMigration::addPrimaryKey(): Add a primary key
yiidbMigration::dropPrimaryKey(): Delete a primary key
yiidbMigration::addForeignKey(): Add a foreign key
yiidbMigration::dropForeignKey( ): Delete a foreign key
yiidbMigration::createIndex(): Create an index
yiidbMigration::dropIndex(): Delete an index

Submit migration

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

yii migrate

This command will list all uncommitted migrations so far. If you determine that you need to submit these migrations, it will run the up() or safeUp() method in each new migration class one after another in the order of the timestamp 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.

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

Tips: The migration tool will automatically create a migration table in the database specified in the yiiconsolecontrollersMigrateController::db option of the command. By default, it is specified by the db application component.

有时,你可能只需要提交一个或者少数的几个迁移,你可以使用该命令指定需要执行的条数,而不是执行所有的可用迁移。例如,如下命令将会尝试提交前三个可用的迁移:

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() 使用一个可以被 strtotime() 解析的字符串
yii migrate/to m150101_185401_create_news_table  # using full name 使用全名
yii migrate/to 1392853618             # using UNIX timestamp 使用 UNIX 时间戳

   

如果在指定要提交的迁移前面还有未提交的迁移,那么在执行这个被指定的迁移之前,这些还未提交的迁移会先被提交。

如果被指定提交的迁移在之前已经被提交过,那么在其之后的那些迁移将会被还原。

还原迁移

你可以使用如下命令来还原其中一个或多个意见被提交过的迁移:

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 migrate/history   # 显示最近10次提交的迁移
yii migrate/history 5  # 显示最近5次提交的迁移
yii migrate/history all # 显示所有已经提交过的迁移
yii migrate/new     # 显示前10个还未提交的迁移
yii migrate/new 5    # 显示前5个还未提交的迁移
yii migrate/new all   # 显示所有还未提交的迁移

   

修改迁移历史

有时候你也许需要简单的标记一下你的数据库已经升级到一个特定的迁移,而不是实际提交或者是还原迁移。这个经常会发生在你手动的改变数据库的一个特定状态,而又不想相应的迁移被重复提交。那么你可以使用如下命令来达到目的:

yii migrate/mark 150101_185401           # 使用时间戳来指定迁移
yii migrate/mark "2015-01-01 18:54:01"       # 使用一个可以被 strtotime() 解析的字符串
yii migrate/mark m150101_185401_create_news_table  # 使用全名
yii migrate/mark 1392853618             # 使用 UNIX 时间戳

   

该命令将会添加或者删除 migration 表当中的某几行数据来表明数据库已经提交到了指定的某个迁移上。执行这条命令期间不会有任何的迁移会被提交或还原。

自定义迁移

有很多方法可以自定义迁移命令。

使用命令行选项

迁移命令附带了几个命令行选项,可以用来自定义它的行为:

interactive: boolean (默认值为 true),指定是否以交互模式来运行迁移。当被设置为 true 时,在命令执行某些操作前,会提示用户。如果你希望在后台执行该命令,那么你应该把它设置成 false。

migrationPath: string (默认值为 @app/migrations),指定存放所有迁移类文件的目录。该选项可以是一个目录的路径,也可以是 路径别名。需要注意的是指定的目录必选存在,否则将会触发一个错误。

migrationTable: string (默认值为 migration),指定用于存储迁移历史信息的数据库表名称。如果这张表不存在,那么迁移命令将自动创建这张表。当然你也可以使用这样的字段结构: version
 varchar(255) primary key, apply_time integer 来手动创建这张表。

db: string (默认值为 db),指定数据库 application component 的 ID。它指的是将会被该命令迁移的数据库。

templateFile: string (defaults to @yii/views/migration.php),指定生产迁移框架代码类文件的模版文件路径。该选项即可以使用文件路径来指定,也可以使用路径 别名 来指定。该模版文件是一个可以使用预定义变量 $className 来获取迁移类名称的 PHP 脚本。

如下例子向我们展示了如何使用这些选项:

例如,如果我们需要迁移一个 forum 模块,而该迁移文件放在该模块下的 migrations 目录当中,那么我们可以使用如下命令:

# 在 forum 模块中以非交互模式进行迁移
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0

   

全局配置命令

在运行迁移命令的时候每次都要重复的输入一些同样的参数会很烦人,这时候,你可以选择在应用程序配置当中进行全局配置,一劳永逸:

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

   

如上所示配置,在每次运行迁移命令的时候,backend_migration 表将会被用来记录迁移历史。你再也不需要通过 migrationTable 命令行参数来指定这张历史纪录表了。

迁移多个数据库

默认情况下,迁移将会提交到由 db application component 所定义的同一个数据库当中。如果你需要提交到不同的数据库,你可以像下面那样指定 db 命令行选项,

yii migrate --db=db2

   

上面的命令将会把迁移提交到 db2 数据库当中。

偶尔有限时候你需要提交 一些 迁移到一个数据库,而另外一些则提交到另一个数据库。为了达到这个目的,你应该在实现一个迁移类的时候指定需要用到的数据库组件的 ID , 如下所示:

use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
  public function init()
  {
    $this->db = &#39;db2&#39;;
    parent::init();
  }
}

   

即使你使用 db 命令行选项指定了另外一个不同的数据库,上面的迁移还是会被提交到 db2 当中。需要注意的是这个时候迁移的历史信息依然会被记录到 db 命令行选项所指定的数据库当中。

如果有多个迁移都使用到了同一个数据库,那么建议你创建一个迁移的基类,里面包含上述的 init() 代码。然后每个迁移类都继承这个基类就可以了。

提示:除了在 yii\db\Migration::db 参数当中进行设置以外,你还可以通过在迁移类中创建新的数据库连接来操作不同的数据库。然后通过这些连接再使用 DAO 方法 来操作不同的数据库。

另外一个可以让你迁移多个数据库的策略是把迁移存放到不同的目录下,然后你可以通过如下命令分别对不同的数据库进行迁移:

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

   

第一条命令将会把 @app/migrations/db1 目录下的迁移提交到 db1 数据库当中,第二条命令则会把 @app/migrations/db2 下的迁移提交到 db2 数据库当中,以此类推。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

更多yii2.0数据库迁移教程相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn