目录
1. 创建迁移
2. 事务迁移
3.使用迁移
4. 恢复迁移
5. 重做迁移
6. 显示迁移信息
7. 编辑迁移历史
8. 自定义迁移命令
首页 后端开发 php教程 Yii框架官方指南系列增补版27——使用数据库:数据库迁移

Yii框架官方指南系列增补版27——使用数据库:数据库迁移

Feb 15, 2017 am 09:10 AM



注意: yii从版本1.1.6以后才开始支持数据库迁移特性。

和源码一样,数据库的结构也随着我们开发和维护数据库驱动应用而不断壮大.例如,在开发期间,我们可能想要添加一个新的表; 或者在应用投入生产期以后,我们可能会意识到需要在某个列上添加索引. 跟踪这些数据库结构的改变(被称作迁移)和操作源代码一样很重要.如果源码和数据库不同步了,可能这个系统都会中断。正是因为这个原因,Yii框架提供了数据库迁移工具,以便跟踪数据库迁移历史,应用新的迁移,或者恢复旧的迁移.

下面的步骤显示了如何在开发期间使用数据库迁移:
Tim添加一个新的迁移(e.g. create a new table)
Tim提交一个新的迁移到版本控制工具(e.g. SVN, GIT)
Doug 从版本控制工具更新并取出一个新的迁移
Doug 应用新的迁移到本地开发版本的数据库

Yii框架通过yiic migrate命令行工具支持数据库迁移. 这个工具支持创建新的迁移,应用/恢复/取消迁移,并且显示迁移历史和新的迁移。

接下来,我们将会描述如何使用这个工具。

注意: 当使用命令行迁移工具进行迁移时最好使用application目录下的 yiic (e.g. cd path/to/protected)而不是系统目录下的. 确保拥有protected\migrations 文件夹并且它是可写的. 还要检查在protected/config/console.php中是否配置了数据库连接 。

1. 创建迁移

想要创建一个新的迁移 (例如创建一个news表), 我们可以运行如下命令:

yiic migrate create <name>
登录后复制

参数name是必须的,指定了关于这个迁移的非常简短的描述(e.g. create_news_table). 正如我们在下面要展示的, name参数是PHP类名的一部分。并且它只能包含字母,数字和下划线。

yiic migrate create create_news_table
登录后复制

上面的命令将会在路径protected/migrations下创建一个新的名为m101129_185401_create_news_table.php的文件,该文件包含了下列代码:

class m101129_185401_create_news_table extends CDbMigration
{
    public function up(){}

    public function down()
    {
        echo "m101129_185401_create_news_table does not support migration down.\n";
        return false;
    }

    /*
    // implement safeUp/safeDown instead if transaction is needed
    public function safeUp(){}

    public function safeDown(){}
    */
}
登录后复制

注意这个类名和文件名一样,都是m_模式,其中表示迁移创建时的UTC时间戳 (格式为yymmdd_hhmmss) , 而 是从命令的命名参数中获取的。

up() 方法应该包含实现数据库迁移的代码, 而down() 方法包含的代码则用于还原up()方法中的操作。

有时候, 实现down()中的操作是不可能的。比如, 如果在up()方法中删除表的某一行, 就不能在down方法中恢复。 在这种情况下, 迁移被称作不可逆的,这意味着我们不能回滚到数据库的前一个状态。 在上面生成的代码中, down() 方法返回false来表明迁移的不可逆

Info: 从版本1.1.7开始, 如果up() 或者down() 方法返回false, 下面的所有迁移都会被取消。而在版本1.1.6中, 必须抛出异常来取消下面的迁移。

让我们用一个例子来展示创建一个news表的迁移.

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

    public function down()
    {
        $this->dropTable('tbl_news');
    }
}
登录后复制

基类 CDbMigration 提供了一系列的方法来操作数据和数据库,例如, CDbMigration::createTable 会创将数据库表,CDbMigration::insert 会插入一行数据。这些方法都使用CDbMigration::getDbConnection()返回的数据库连接, 默认是Yii::app()->db。

Info: 你可能注意到CDbMigration提供的数据库方法和CDbCommand中的很类似。的确,它们基本上相同,除了CDbMigration方法会计算执行所耗的时间以及打印一些方法参数的信息。

也可以扩展操作数据库的方法,比如:

public function up()
{
    $sql = "CREATE TABLE IF NOT EXISTS user(
        id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
        username VARCHAR(32) NOT NULL,
        password VARCHAR(32) NOT NULL,
        email VARCHAR(32) NOT NULL
    ) ENGINE=MyISAM";
    $this->createTableBySql('user',$sql);
}
public function createTableBySql($table,$sql){
    echo " > create table $table ...";
    $time=microtime(true);
    $this->getDbConnection()->createCommand($sql)->execute();
    echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n";
}
登录后复制

2. 事务迁移

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语句会引发冲突.

3.使用迁移

想要使用所有有效的新迁移 (i.e., make the local database up-to-date), 运行下面的命令:

yiic migrate
登录后复制

这个命令会显示所有新迁移的列表. 如果你确定使用迁移, 它将会在每一个新的迁移类中运行up()方法, 一个接着一个, 按照类名中的时间戳的顺序.

在使用迁移之后, 迁移工具会在一个数据表tbl_migration中写一条记录——允许工具识别应用了哪一个迁移. 如果tbl_migration表不存在 ,工具会在配置文件中db指定的数据库中自动创建。

有时候, 我们可能指向应用一条或者几条迁移. 那么可以运行如下命令:

yiic migrate up 3
登录后复制

这个命令会运行3个新的迁移. 该表value的值3将允许我们改变将要被应用的迁移的数目。

我们还可以通过如下命令迁移数据库到一个指定的版本:

yiic migrate to 101129_185401
登录后复制

也就是我们使用数据库迁移名中的时间戳部分来指定我们想要迁移到的数据库的版本。如果在最后应用的数据库迁移和指定的迁移之间有多个迁移, 所有这些迁移都会被应用. 如果指定迁移已经使用过了, 所有之后应用的迁移都会恢复。

4. 恢复迁移

想要恢复最后一个或几个已应用的迁移,我们可以运行如下命令:

yiic migrate down [step]
登录后复制

其中选项 step 参数指定了要恢复的迁移的数目. 默认是1, 意味着恢复最后一个应用的迁移.

正如我们之前所描述的, 不是所有的迁移都能恢复. 尝试恢复这种迁移会抛出异常并停止整个恢复进程。

5. 重做迁移

重做迁移意味着第一次恢复并且之后应用指定的迁移. 这个可以通过如下命令来实现:

yiic migrate redo [step]
登录后复制

其中可选的step参数指定了重做多少个迁移 . 默认是1, 意味着重做最后一个迁移.

6. 显示迁移信息

除了应用和恢复迁移之外, 迁移工具还可以显示迁移历史和被应用的新迁移。

yiic migrate history [limit]
yiic migrate new [limit]
登录后复制

其中可选的参数 limit 指定克显示的迁移的数目。如果limit没有被指定,所有的有效迁移都会被显示。

第一个命令显示已经被应用的迁移, 而第二个命令显示还没被应用的迁移。

7. 编辑迁移历史

有时候, 我们可能想要在没有应用和恢复相应迁移的时候编辑迁移历史来指定迁移版本. 这通常发生在开发一个新的迁移的时候. 我们使用下面的命令来实现这一目标.

yiic migrate mark 101129_185401
登录后复制

这个命令和yiic migrate to命令非常类似, 但它仅仅只是编辑迁移历史表到指定版本而没有应用或者恢复迁移。

8. 自定义迁移命令

有多种方式来自定义迁移命令。

使用命令行选项

迁移命令需要在命令行中指定四个选项:

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.

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 the migrations sub-directory under the application base path.

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.

connectionID: string, specifies the ID of the database application component. Defaults to '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.
登录后复制

想要指定这些选项, 使用如下格式的迁移命令执行即可:

yiic migrate up --option1=value1 --option2=value2 ...
登录后复制

例如, 如果我们想要迁移一个论坛模块,它的迁移文件都放在模块的迁移文件夹中,可以使用如下命令:

yiic migrate up --migrationPath=ext.forum.migrations
登录后复制

注意在你设置布尔选项如interactive的时候,使用如下方式传入1或者0到命令行:

yiic migrate --interactive=0
登录后复制

配置全局命令

命令行选项允许我们快速配置迁移命令, 但有时候我们可能想要只配置一次命令. 例如, 我们可能想要使用不同的表来保存迁移历史, 或者我们想要使用自定义的迁移模板。我们可以通过编辑控制台应用的配置文件来实现,如下所示:

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

现在如果我们运行迁移命令,上述配置将会生效,而不需要我们每一次在命令行中都输入那么多选项信息。

以上就是Yii框架官方指南系列增补版27——使用数据库:数据库迁移的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP中如何使用Yii框架 PHP中如何使用Yii框架 Jun 27, 2023 pm 07:00 PM

随着Web应用程序的快速发展,现代Web开发已成为一项重要技能。许多框架和工具可用于开发高效的Web应用程序,其中Yii框架就是一个非常流行的框架。Yii是一个高性能、基于组件的PHP框架,它采用了最新的设计模式和技术,提供了强大的工具和组件,是构建复杂Web应用程序的理想选择。在本文中,我们将讨论如何使用Yii框架来构建Web应用程序。安装Yii框架首先,

Yii框架中间件:为应用程序提供多重数据存储支持 Yii框架中间件:为应用程序提供多重数据存储支持 Jul 28, 2023 pm 12:43 PM

Yii框架中间件:为应用程序提供多重数据存储支持介绍中间件(middleware)是Yii框架中的一个重要概念,它为应用程序提供了多重数据存储支持。中间件的作用类似于一个过滤器,它能够在应用程序的请求和响应之间插入自定义代码。通过中间件,我们可以对请求进行处理、验证、过滤,然后将处理后的结果传递给下一个中间件或最终的处理程序。Yii框架中的中间件使用起来非常

使用Yii框架实现网页缓存和页面分块的步骤 使用Yii框架实现网页缓存和页面分块的步骤 Jul 30, 2023 am 09:22 AM

使用Yii框架实现网页缓存和页面分块的步骤引言:在Web开发过程中,为了提高网站的性能和用户体验,常常需要对页面进行缓存和分块处理。Yii框架提供了强大的缓存和布局功能,可以帮助开发者快速实现网页缓存和页面分块,本文将介绍如何使用Yii框架进行网页缓存和页面分块的实现。一、网页缓存开启网页缓存在Yii框架中,可以通过配置文件来开启网页缓存。打开主配置文件co

使用Yii框架创建游戏攻略网站 使用Yii框架创建游戏攻略网站 Jun 21, 2023 pm 01:45 PM

近年来,随着游戏行业的快速发展,越来越多的玩家开始寻找游戏攻略来帮助游戏过关。因此,创建一个游戏攻略网站可以让玩家们更加方便地获取游戏攻略,同时也能为玩家提供更好的游戏体验。在创建这样一个网站时,我们可以使用Yii框架来进行开发。Yii框架是一个基于PHP编程语言的Web应用开发框架。它具有高效、安全、扩展性强等特点,可以为我们更快速、高效地创建一个游戏攻略

使用Zend框架实现数据库迁移(Migrations)的步骤 使用Zend框架实现数据库迁移(Migrations)的步骤 Jul 28, 2023 pm 05:54 PM

使用Zend框架实现数据库迁移(Migrations)的步骤引言:数据库迁移是在软件开发过程中不可或缺的一部分,它的作用是为了方便团队在开发中对数据库结构的修改和版本控制。而Zend框架提供了一套强大的数据库迁移工具,可以帮助我们轻松地管理数据库结构的变动。本文将介绍如何使用Zend框架实现数据库迁移的步骤,并附上相应的代码示例。步骤1:安装Zend框架首先

PHP和SQLite:如何进行数据库迁移和升级 PHP和SQLite:如何进行数据库迁移和升级 Jul 28, 2023 pm 08:10 PM

PHP和SQLite:如何进行数据库迁移和升级在开发Web应用程序时,数据库迁移和升级是一个很常见的任务。而对于使用PHP和SQLite的开发者来说,这个过程可能会比较复杂。本文将介绍如何使用PHP和SQLite进行数据库迁移和升级,并提供一些代码示例供参考。创建SQLite数据库首先,我们需要创建一个SQLite数据库。使用SQLite数据库非常方便,我们

Yii框架中间件:为应用程序添加日志记录和调试功能 Yii框架中间件:为应用程序添加日志记录和调试功能 Jul 28, 2023 pm 08:49 PM

Yii框架中间件:为应用程序添加日志记录和调试功能【引言】在开发Web应用程序时,我们通常需要添加一些附加功能以提高应用的性能和稳定性。Yii框架提供了中间件的概念,使我们能够在应用程序处理请求之前和之后执行一些额外的任务。本文将介绍如何使用Yii框架的中间件功能来实现日志记录和调试功能。【什么是中间件】中间件是指在应用程序处理请求之前和之后,对请求和响应做

在Yii框架中使用控制器(Controllers)处理Ajax请求的方法 在Yii框架中使用控制器(Controllers)处理Ajax请求的方法 Jul 28, 2023 pm 07:37 PM

在Yii框架中,控制器(Controllers)扮演着处理请求的重要角色。除了处理常规的页面请求之外,控制器还可以用于处理Ajax请求。本文将介绍在Yii框架中处理Ajax请求的方法,并提供代码示例。在Yii框架中,处理Ajax请求可以通过以下步骤进行:第一步,创建一个控制器(Controller)类。可以通过继承Yii框架提供的基础控制器类yiiwebCo

See all articles