数据库的结构也同源代码一样随着我们开发的进行而不断的发生着改变。在开发过程中,一般的我们需要像管理我们的源代码一样记录下数据库结构的整个变化过程,以便代码还原到指定版本后,数据库能同步的还原到指定的版本与源代码同步。为了方便这一操作,Yii给我们提供了Yiic migrate 这个命令,对应的也有一个 CDbMigration 类来描述各个版本之间的信息,从而实现通过命令来还原或者更新数据库到指定的版本。

 
Yii的数据迁移代码都存放在 /protected/migrations 文件夹中。如果不存在改文件夹请自行创建。执行命令:
cd  protected
yiic migrate create tbl_user

F:\xampp\htdocs\swsg10\backend\protected>yiic help migrate
USAGE
yiic migrate [action] [parameter]

DESCRIPTION
This command provides support for database migrations. The optional
'action' parameter specifies which specific migration task to perform.
It can take these values: up, down, to, create, history, new, mark.
If the 'action' parameter is not given, it defaults to 'up'.
Each action takes different parameters. Their usage can be found in
the following examples.

EXAMPLES
* yiic migrate
Applies ALL new migrations. This is equivalent to 'yiic migrate up'.

* yiic migrate create create_user_table
Creates a new migration named 'create_user_table'.

* yiic migrate up 3
Applies the next 3 new migrations.

* yiic migrate down
Reverts the last applied migration.

* yiic migrate down 3
Reverts the last 3 applied migrations.

* yiic migrate to 101129_185401
Migrates up or down to version 101129_185401.

* yiic migrate mark 101129_185401
Modifies the migration history up or down to version 101129_185401.
No actual migration will be performed.

* yiic migrate history
Shows all previously applied migration information.

* yiic migrate history 10
Shows the last 10 applied migrations.

* yiic migrate new
Shows all new migrations.

* yiic migrate new 10
Shows the next 10 migrations that have not been applied.

F:\xampp\htdocs\swsg10\backend\protected>

1 生成数据库表:       yiic migrate
2 降低N个版本: yiic migrate down n
3 升级N个版本: yiic migrate up n
4 升级到指定版本: yiic migrate to 101129_185401
5 重新执行步骤: yiic migrate redo [step]
6 显示迁移历史: yiic migrate history [limit]
7 显示未应用的迁移: yiic migrate new [limit]

这里有两点需要说明一下:

  1. 执行yiic命令是需要配置好相关的环境变量面的Yiic命令找不到Yii框架的代码。
  2. 命令中 tbl_user 是我们要做的更改的简要说明,这里我用的表明,当然也可以是其它的说明,一般只作为 migrate 生成类名的一部分,方便理解。帖一下执行过程吧
E:\WebRoot\TrackStar\protected>yiic migrate create tbl_user

Yii Migration Tool v1.0 (based on Yii v1.1.9-dev)

Create new migration 'E:\WebRoot\TrackStar\protected\migrations\m120406_063814_tbl_user.php'? [yes|no] yes
New migration created successfully. E:\WebRoot\TrackStar\protected>

执行完这个命令就会在 /protected/migrations 文件夹中生成要处理的PHP文件,如下图:

生成的这个文件代码也非常简单:
1 class m120406_063814_tbl_user extends CDbMigration{
 2     public function up(){
3 // 新数据库版本的代码,可以是创建新表、修改表结构、增删数据 等等
4 // 具体可以参考 Yii文档的 CDbMigration 类说明。
5 $this->createTable('tbl_user', array(
6 'id' => 'pk',
7 'username' => 'VARCHAR(128) NOT NULL',
8 'password' => 'VARCHAR(128) NOT NULL',
9 'email' => 'VARCHAR(128) NOT NULL'
10 ));
11 }
12
13 public function down(){
14 // 这里是对应up写的还原部分。
15 // 如果up函数中写的是建表,这里可以删除表,如果up中写的是增加新元素,这里可以是删除。
// 如果是初始版本,不允许还原的话,将此函数返回一个false即可。
17 $this->dropTable('tbl_user');
18 }
19
20 /*
21 // 如果要迁移的数据牵扯多个表同步操作,可以通过下面两个方法来实现事务的迁移
22 public function safeUp(){
23 }
24
25 public function safeDown(){
26 }
27 */
28 }
 

以上代码我注释的很清楚了,我们的第一个版本就只是简单的创建了个tbl_user表,如果再还原到初始情况的话,就将这个表也drop掉。倘若你对于 createTable 之类的方法不了解,可以参考Yii文档的CDbMigration类说明,一般的百度一下就会有好多出来,如果实在找不到,我会在本文最后列出来。

  在执行命令之前,我们需要修改下:/protected/config/console.php 中的配置,让命令能顺利的找到我们的数据库:

1 components'=>array(
2 ‘db'=>array(
3 'connectionString' => 'mysql:host=localhost;dbname=trackstar',
4 'emulatePrepare' => true,
5 'username' => 'root',
6 'password' => '',
7 'charset' => 'utf8',
8 ),

OK, 执行命令:

E:\WebRoot\TrackStar\protected>yiic migrate up

Yii Migration Tool v1.0 (based on Yii v1.1.9-dev)

Total 1 new migration to be applied:
m120406_063814_tbl_user Apply the above migration? [yes|no] yes
*** applying m120406_063814_tbl_user
> create table tbl_user ... done (time: 0.056s)
*** applied m120406_063814_tbl_user (time: 0.067s) Migrated up successfully. E:\WebRoot\TrackStar\protected>

OK, 看我们的数据库:

数据库表成功建立,其中, tbl_migration 表是用来管理每次数据库操作过程的,暂不细说。

  再还原回去:

E:\WebRoot\TrackStar\protected>yiic migrate down

Yii Migration Tool v1.0 (based on Yii v1.1.9-dev)

Total 1 migration to be reverted:
m120406_063814_tbl_user Revert the above migration? [yes|no] yes
*** reverting m120406_063814_tbl_user
> drop table tbl_user ... done (time: 0.056s)
*** reverted m120406_063814_tbl_user (time: 0.069s) Migrated down successfully. E:\WebRoot\TrackStar\protected>

Ok,测试没问题了,我们再建一个新版本,用来想表中添加五条记录:

yiic migrate create tbl_user_adddata

生成的代码:

1 class m120406_072631_tbl_user_adddata extends CDbMigration
2 {
3 public function up(){
4 $this->insert('tbl_user', array('username' => 'test1', 'password' => 'pass1',
5 'email'=> 'test1@example.com'));
6 $this->insert('tbl_user', array('username' => 'test2', 'password' => 'pass2',
7 'email'=> 'test2@example.com'));
8 $this->insert('tbl_user', array('username' => 'test3', 'password' => 'pass3',
9 'email'=> 'test3@example.com'));
10 $this->insert('tbl_user', array('username' => 'test4', 'password' => 'pass4',
11 'email'=> 'test4@example.com'));
12 $this->insert('tbl_user', array('username' => 'test5', 'password' => 'pass5',
13 'email'=> 'test5@example.com'));
14
15 }
16
17 public function down(){
18 $this->delete('tbl_user', 'username = "test1"');
19 $this->delete('tbl_user', 'username = "test2"');
20 $this->delete('tbl_user', 'username = "test3"');
21 $this->delete('tbl_user', 'username = "test4"');
22 $this->delete('tbl_user', 'username = "test5"');
23 }
24
25 .....

这样就又加了个新版本,只要用命令:

yiic migrate up 1

这样就更新到新版本了, 使用

yiic migrate down 1

Customizing Migration Command 定制迁移命令

There are several ways to customize the migration command.

有几种方法来定制迁移命令。

Use Command Line Options 使用命令行选项

The migration command comes with four options that can be specified in command line:

在命令行中迁移命令可以使用如下四个选项

  • interactive: boolean, specifies whether to perform migrations in an interactive mode. Defaults to true, meaning the user will be prompted when performing a specific migration. You may set this to false should the migrations be done in a background process.

    boolean,指定是否执行交互模式的迁移。默认为true,这意味着用户将被提示时执行特定迁移。您可以设置为false应该在做一个后台进程迁移

  • migrationPath: string, specifies the directory storing all migration class files. This must be specified in terms of a path alias, and the corresponding directory must exist. If not specified, it will use themigrations

    sub-directory under the application base path.

    string,指定存储所有迁移的类文件的目录。必须指定路径别名以及相应的目录必须存在。如果没有指定,它将使用应用程序的根路径下的themigrations子目录

  • migrationTable: string, specifies the name of the database table for storing migration history information. It defaults to tbl_migration. The table structure is version varchar(255) primary key, apply_time integer.string,,指定存储迁移历史信息的数据库表的名称。默认tbl_migration。表的结构是版本VARCHAR(255)主键,apply_time整数。

  • connectionID: string, specifies the ID of the database application component. Defaults to 'db'.string,指定的数据库应用程序组件的ID。默认为'DB'。

  • templateFile: string, specifies the path of the file to be served as the code template for generating the migration classes. This must be specified in terms of a path alias (e.g.application.migrations.template). If not set, an internal template will be used. Inside the template, the token {ClassName} will be replaced with the actual migration class name.

    string,指定文件的路径,作为担任产生迁移类的代码模板。这必须指定一个路径别名(eg application.migrations.template)。如果没有设置,将使用一个内部模板。在该模板中,标记{ClassName}将被替换为实际的迁移类的名称。

To specify these options, execute the migrate command using the following format

实例如下

yiic migrate up --option1=value1 --option2=value2 ...

For example, if we want to migrate for a forum module whose migration files are located within the module'smigrations directory, we can use the following command:

例如,如果我们要迁移的一个论坛模块,其迁移位于模块的migrations目录内的文件,我们可以使用下面的命令:

yiic migrate up --migrationPath=ext.forum.migrations

Configure Command Globally配置全局命令

While command line options allow us to configure the migration command on-the-fly, sometimes we may want to configure the command once for all. For example, we may want to use a different table to store the migration history, or we may want to use a customized migration template. We can do so by modifying the console application's configuration file like the following,

虽然命令行选项允许我们配置迁移命令,有时我们可能需要一次配置所有的命令。例如,我们可能要使用不同的表来存储迁移历史,或者我们可能要使用一个定制的迁移模板。我们可以通过类似下面的控制台应用程序的配置文件修改,

return array(
......
'commandMap'=>array(
'migrate'=>array(
'class'=>'system.cli.commands.MigrateCommand',
'migrationPath'=>'application.migrations',
'migrationTable'=>'tbl_migration',
'connectionID'=>'db',
'templateFile'=>'application.migrations.template',
),
......
),
......
);

Now if we run the migrate command, the above configurations will take effect without requiring us to enter the command line options every time.

现在,如果我们运行migrate命令,上述配置将一直有效,而无需每次配置。

事务迁移

Info: 事务迁移的特性从版本1.1.7起开始支持.

在复杂的数据库迁移中, 我们经常想要确保每一个迁移都是成功的还是失败的,以便数据库保持一致性和完整性。 为了实现这个目标我们可以利用数据库事务.

我们可以明确地开启数据库事务并附上其他数据库相关的包含事务的代码,例如:

class m101129_185401_create_news_table extends CDbMigration
{
public function up()
{
$transaction=$this->getDbConnection()->beginTransaction();
try
{
$this->createTable('tbl_news', array(
'id' => 'pk',
'title' => 'string NOT NULL',
'content' => 'text',
));
$transaction->commit();
}catch(Exception $e){
echo "Exception: ".$e->getMessage()."\n";
$transaction->rollback();
return false;
}
} // ...similar code for down()
}

然而, 一个更简单的获取事务支持的方法是实现safeUp() 方法来取代 up(), 以及safeDown() 来取代down(). 例如:

class m101129_185401_create_news_table extends CDbMigration
{
public function safeUp()
{
$this->createTable('tbl_news', array(
'id' => 'pk',
'title' => 'string NOT NULL',
'content' => 'text',
));
} public function safeDown()
{
$this->dropTable('tbl_news');
}
}

当Yii执行迁移的时候, 将会开启数据库迁移然后调用 safeUp() 或者 safeDown(). 如果safeUp() 和 safeDown()出现任何错误, 事务将会回滚, 以确保数据库保持一致性和完整性.

Note: 不是所有的DBMS都支持事务. 并且一些DB查询不能放到事务中. 在这种情况下, 你比许实现up()和down()取而代之. 对MySQL而言, 一些SQL语句会引发冲突.

 
 
 

yiic 数据库迁移工具的更多相关文章

  1. flask-admin章节三:数据库迁移工具 alembic初步使用

    1. 概述 基于flask框架构建web,一般会使用sqlchemy(在flask中使用sqlchemy可以参考这里)作为数据库引擎. 这样业务的逻辑就可以做到不跟具体的数据库类型相耦合,具体后端业务 ...

  2. PHP系列 | ThinkPHP5数据库迁移工具 migration

    了解更多,请关注微信公众号 ThinkPHP5数据库迁移工具 migration 什么是Migration? migration用谷歌翻译是移民的意思,在PHP中我们将它理解为迁移,将Migratio ...

  3. TP5 数据库迁移工具 migrate 教程

    第一步: 安装compose,不赘述,安装详情可百度或查看https://pkg.phpcomposer.com/#how-to-install-composer 第二步: 通过 composer   ...

  4. tp5 migrate数据库迁移工具

    tp5相对与tp3.2有很大的不同 migrate是其中一点,通过migrate程序员可以在php代码中创建数据库修改回滚等操作 首先下载migrate扩展,命令行到当前项目目录下执行 compose ...

  5. 数据库迁移工具Navicat Premium之OracleToMysql

    一.问题 由于工作需要,需要把业务库的数据库从oracle签到mysql,免费开源 二.解决办法 2.1:ETL单个对象进行转移(最笨的办法,所以抛弃掉了) 2.2:使用Navicat Premium ...

  6. 四十七:数据库之alembic数据库迁移工具的基本使用

    在一般情况下,如果修改了模型,如增加或者删除了字段,SQLAlchemy是不会更新的,这就需要使用alembic来实现 使用alembic步骤:一:定义好模型二:使用alembic创建一个仓库:ale ...

  7. java 数据库迁移工具 flyway

    官方 https://github.com/flyway/flyway 简易demo https://github.com/deadzq/flyway-demo 主要在配置文件上做改动

  8. 数据库迁移工具DBMigration

  9. yii 数据库迁移

    在我们开发程序的过程中,数据库的结构也是不断调整的.我们的开发中要保证代码和数据库库的同步.因为我们的应用离不开数据库.例如: 在开发过程中,我们经常需要增加一个新的表,或者我们后期投入运营的产品,可 ...

随机推荐

  1. 利用openssl进行RSA加密解密

    openssl是一个功能强大的工具包,它集成了众多密码算法及实用工具.我们即可以利用它提供的命令台工具生成密钥.证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密. RSA是 ...

  2. <a>多颜色标签点击之后保持原色的一次实践, Ext Panel下解决及通用方案思路

    代码为片段, 需要自行设置全部环境方可全部运行. 案例背景 使用Ext开发了一个表格,需要根据一列值来动态设置颜色. 效果如下: 说明: 不同行显示不同的内容, 作为标题行, 可以点击链接到其他地方. ...

  3. Golang,用map写个单词统计器

    Golang中也有实用的泛型编程模板.如map.据Go官方团队称,其实现为Hash表,而非类似cpp或Java的红黑树.所以理论上速度更能快上几个等级(Hash与红黑树的效率对比可以看我的文章C++中 ...

  4. 洛谷 P1108 低价购买

    P1108 低价购买 标签 动态规划 难度 提高+/省选- 题目描述 "低价购买"这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:& ...

  5. 基于libuv库的UDP收/发广播消息代码实现

    uv_send(发送端): #include "uv.h" #include "task.h" #include <stdio.h> #includ ...

  6. 一个基本jquery的评论留言模块

    <div class="productDiscuss"> <div class="title"><span class=" ...

  7. Asp.Net细节性问题精萃

    1.<%=…%>与<%#… %>的区别: 答:<%=…%>是在程序执行时调用,<%#… %>是在DataBind()方法之后被调用 2.控件接收哪些类型 ...

  8. 【转】C# Excel 导入到 Access数据库表(winForm版)

    /// <summary> /// 获取Excel文件 /// </summary> /// <param name="sender">< ...

  9. HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)

    看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现:虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难 ...

  10. JsTree异步加载数据实现多级菜单

    最近在搞一个项目的维护,有一个问题是把原来的树导航变成多级的,原来的那个导航是JsTree的,但我又不熟悉,遂头疼了好久... 终于,他还是出来了,下面就贴上主要代码和思路,因为我在搞这个东西的时候在 ...