[Yii2笔记]020对数据库应用、恢复、重做、列出和自定义迁移(migration) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#applying-migrations
3、Applying Migrations(应用迁移)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#reverting-migrations
4、Reverting Migrations(恢复迁移)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#redoing-migrations
5、Redoing Migrations(重做迁移)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#listing-migrations
6、Listing Migrations(列出迁移)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#modifying-migration-history
7、Modifying Migration History(修改迁移历史)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#customizing-migrations
8、Customizing Migrations(自定义迁移)
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#migrating-multiple-databases
9、Migrating Multiple Databases(迁移多数据库)
本文主题:对数据库应用、恢复、重做、列出和自定义迁移(migration)
3、Applying Migrations(应用迁移)
升级一个数据库到最新的结构,你需要使用以下命令应用所有的新迁移:
yii migrate
此命令将列出所有没有被应用的迁移,如果你确定要应用这些迁移,它将运行每个新迁移中的up()或safeUp()方法,按照它们的时间顺序一个接一个。如果有一个迁移失败,命令将退出,其后的迁移将不再被应用。
//应用所有迁移实例:
D:\phpwork\basic>yii migrate
Yii Migration Tool (based on Yii v2.0.8)
Creating migration history table "migration"...Done.
Total 6 new migrations to be applied:
m170313_082453_create_news_table
m170314_033848_create_post
m170314_054507_drop_post
m170314_054954_add_position_column_to_post
m170314_060321_drop_position_column_from_post
m170314_060957_create_junction_for_post_and_tag
Apply the above migrations? (yes|no) [no]:n
D:\phpwork\basic>
小贴士:如果你不想使用命令行,你可以试试web shell扩展: https://github.com/samdark/yii2-webshell
为每个应用成功的迁移,命令会在名为migration的表中插入一行记录,用于记录此迁移已经成功应用。这样就允许迁移工具分辨出已应用和未应用的迁移。
信息:迁移工具将使用操作命令在数据库中自动创建migration表。默认情况 下,数据库由db应用组件定义。
有时,你仅想应用一个或几个新迁移,而不是所有的,你需要定义运行命令时需要应用的迁移数量。例如,以下命令将应用3个有效的迁移:
yii migrate 3
//应用最先的3个迁移实例
D:\phpwork\basic>yii migrate 3
Yii Migration Tool (based on Yii v2.0.8)
Total 3 out of 6 new migrations to be applied:
m170313_082453_create_news_table
m170314_033848_create_post
m170314_054507_drop_post
Apply the above migrations? (yes|no) [no]:y
*** applying m170313_082453_create_news_table
> create table news ... done (time: 0.024s)
*** applied m170313_082453_create_news_table (time: 0.070s)
*** applying m170314_033848_create_post
> create table post ... done (time: 0.021s)
*** applied m170314_033848_create_post (time: 0.035s)
*** applying m170314_054507_drop_post
> drop table post ... done (time: 0.016s)
*** applied m170314_054507_drop_post (time: 0.027s)
3 migrations were applied.
Migrated up successfully.
D:\phpwork\basic>
你也可以使用migrate/to命令对数据库明确定义一个特定的迁移,格式发下:
yii migrate/to 150101_185401 # 使用时间戳指定迁移
yii migrate/to "2015-01-01 18:54:01" # 使用一个可以转换为时间戳的字符串
yii migrate/to m150101_185401_create_news_table # 使用迁移全称
yii migrate/to 1392853618 # 使用UNIX时间戳
如果有任何一个未应用的迁移比指定的那个迁移时间更早,则在应用指定迁移之前将会先应用这些迁移。 如果指定的迁移已经在此前应用过,那么其后的迁移将被恢复。
//应用迁移发生错误:post表不存在
D:\phpwork\basic>yii migrate
Yii Migration Tool (based on Yii v2.0.8)
Total 3 new migrations to be applied:
m170314_054954_add_position_column_to_post
m170314_060321_drop_position_column_from_post
m170314_060957_create_junction_for_post_and_tag
Apply the above migrations? (yes|no) [no]:y
*** applying m170314_054954_add_position_column_to_post
> add column position integer to table post ...Exception 'yii\db\Exception'
with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'yiibasi
c.post' doesn't exist
The SQL being executed was: ALTER TABLE `post` ADD `position` int(11)''
in D:\phpwork\basic\vendor\yiisoft\yii2\db\Schema.php:633
Error Info:
Array
(
[0] => 42S02
[1] => 1146
[2] => Table 'yiibasic.post' doesn't exist'
)
//重新应用m170314_033848_create_post迁移,将恢复m170314_054507_drop_post迁移
D:\phpwork\basic>yii migrate/to m170314_033848_create_post
Yii Migration Tool (based on Yii v2.0.8)
Total 1 migration to be reverted:
m170314_054507_drop_post
Revert the above migration? (yes|no) [no]:y
*** reverting m170314_054507_drop_post
> create table post ... done (time: 0.028s)
*** reverted m170314_054507_drop_post (time: 0.050s)
1 migration was reverted.
Migrated down successfully.
D:\phpwork\basic>
4、Reverting Migrations(恢复迁移)
要恢复(反操作)一个或多个此前应用的迁移,你可以使用如下命令:
yii migrate/down # 恢复最近应用的迁移
yii migrate/down 3 # 恢复最近应用的3个迁移
注意:不是所有的迁移都可以恢复,尝试恢复此类迁移将产生一个错误并停止整个恢复进程。
//恢复一个迁移
D:\phpwork\basic>yii migrate/down
Yii Migration Tool (based on Yii v2.0.8)
Total 1 migration to be reverted:
m170314_060321_drop_position_column_from_post
Revert the above migration? (yes|no) [no]:y
*** reverting m170314_060321_drop_position_column_from_post
> add column position integer to table post ... done (time: 0.074s)
*** reverted m170314_060321_drop_position_column_from_post (time: 0.093s)
1 migration was reverted.
Migrated down successfully.
D:\phpwork\basic>
5、Redoing Migrations(重做迁移)
重做迁移的意思是先恢复特定的迁移,然后再应用一次,操作如下:
yii migrate/redo # 重做最后一次应用的迁移
yii migrate/redo 3 # 重做最后3次应用的迁移
注意:如果一个迁移没有被恢复,那么你也不能再重做它。
//重做一个迁移
D:\phpwork\basic>yii migrate/redo
Yii Migration Tool (based on Yii v2.0.8)
Total 1 migration to be redone:
m170314_054954_add_position_column_to_post
Redo the above migration? (yes|no) [no]:y
*** reverting m170314_054954_add_position_column_to_post
> drop column position from table post ... done (time: 0.074s)
*** reverted m170314_054954_add_position_column_to_post (time: 0.091s)
*** applying m170314_054954_add_position_column_to_post
> add column position integer to table post ... done (time: 0.057s)
*** applied m170314_054954_add_position_column_to_post (time: 0.069s)
1 migration was redone.
Migration redone successfully.
D:\phpwork\basic>
6、Listing 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 # 列出所有未应用的迁移
//实例,查询最近10个已应用的迁移
D:\phpwork\basic>yii migrate/history
Yii Migration Tool (based on Yii v2.0.8)
Showing the last 2 applied migrations:
(2017-03-16 15:03:55) m170314_033848_create_post
(2017-03-16 15:03:55) m170313_082453_create_news_table
//实例,列出最先的10个未应用的迁移
D:\phpwork\basic>yii migrate/new
Yii Migration Tool (based on Yii v2.0.8)
Found 1 new migration:
m170314_060957_create_junction_for_post_and_tag
D:\phpwork\basic>
7、Modifying Migration History(修改迁移历史)
有时你可能需要标记一下数据库已经更新到某个迁移,而不是真的去应用或取消某个迁移。这种情况通常发生在你已经手动更改了数据库到某个状态,你不需要迁移随后再去应用造成新的修改。你可以使用以下命令达到此目的:
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表,添加或删除行记录标记数据库已经应用到指定迁移了。使用此条命令没有迁移被应用或恢复。
D:\phpwork\basic>yii migrate/new
Yii Migration Tool (based on Yii v2.0.8)
Found 2 new migrations:
m170314_060321_drop_position_column_from_post
m170314_060957_create_junction_for_post_and_tag
//修改迁移历史实例:
D:\phpwork\basic>yii migrate/mark 170314_060321
Yii Migration Tool (based on Yii v2.0.8)
Set migration history at 170314_060321? (yes|no) [no]:y
The migration history is set at 170314_060321.
No actual migration was performed.
D:\phpwork\basic>yii migration/new
Error: Unknown command "migration/new".
D:\phpwork\basic>yii migrate/new
Yii Migration Tool (based on Yii v2.0.8)
Found 1 new migration:
m170314_060957_create_junction_for_post_and_tag
D:\phpwork\basic>
8、Customizing Migrations(自定义迁移)
有几处方法可以自定义迁移命令:使用命令行选项,配置全局命令,命名空间化迁移,独立的迁移 //使用命令行选项(Using Command Line Options) 迁移命令有几个命令行选项可以用来自定义它的行为:
interactive:布尔值(默认true),定义是否在执行迁移时使用互动模式,为true时,在命令确定执行之前用户将被提示,当命令用于在后台进程中执行时你可以将此值设置为false。
migrationPath:字符串(默认"@app/migrations"),定义迁移类文件存储的目录,此选项可以被定义为一个目录路径或是一个目录别名,注意,定义的目录必须存在,否则命令会报错。
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'
]),定义生成迁移代码的模板文件,查看"创建迁移"获取更多信息:
http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#generating-migrations
fields:用于创建迁移代码的字段定义数组,(默认[]),每个定义的格式是COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR,例如:--fields=name:string(12):notNull将生成一个长度为12,不能为空的字符串字段。
下例展示了如何使用这些选项: 例如,如果我们想要迁移一个forum模块,迁移文件位于模块的migrations目录下,我们可以使用以下命令: //使用非交互方式迁移forum模块中的迁移项。
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0
//查看迁移历史,有4个已迁移的记录
D:\phpwork\basic>yii migrate/history
Yii Migration Tool (based on Yii v2.0.8)
Showing the last 4 applied migrations:
(2017-03-20 09:16:42) m170314_060321_drop_position_column_from_post
(2017-03-16 16:18:30) m170314_054954_add_position_column_to_post
(2017-03-16 15:03:55) m170314_033848_create_post
(2017-03-16 15:03:55) m170313_082453_create_news_table
//自定义迁移属性实例,不显示确认提示,直接执行
D:\phpwork\basic>yii migrate/mark 170313_082453 --interactive=0
Yii Migration Tool (based on Yii v2.0.8)
The migration history is set at 170313_082453.
No actual migration was performed.
//查看迁移历史,只有1个已迁移的记录
D:\phpwork\basic>yii migrate/history
Yii Migration Tool (based on Yii v2.0.8)
Showing the last 1 applied migration:
(2017-03-16 15:03:55) m170313_082453_create_news_table
//迁移名称输入不正确则报错:
D:\phpwork\basic>yii migrate/mark 033848
Yii Migration Tool (based on Yii v2.0.8)
Error: The version argument must be either a timestamp (e.g. 101129_185401)
or the full name of a migration (e.g. m101129_185401_create_user_table).
D:\phpwork\basic>
//自定义迁移属性实例,不显示确认提示,直接执行
D:\phpwork\basic>yii migrate/mark 170314_054954 --interactive=0
Yii Migration Tool (based on Yii v2.0.8)
The migration history is set at 170314_054954.
No actual migration was performed.
D:\phpwork\basic>yii migrate/history
Yii Migration Tool (based on Yii v2.0.8)
Showing the last 3 applied migrations:
(2017-03-20 10:14:32) m170314_054954_add_position_column_to_post
(2017-03-20 10:14:32) m170314_033848_create_post
(2017-03-16 15:03:55) m170313_082453_create_news_table
D:\phpwork\basic>yii migrate/new
Yii Migration Tool (based on Yii v2.0.8)
Found 2 new migrations:
m170314_060321_drop_position_column_from_post
m170314_060957_create_junction_for_post_and_tag
D:\phpwork\basic>
配置全局命令(Configuring Command Globally)
为了避免每次运行迁移命令时输出同样的选项,你可以在应用配置中一次性的配置好,配置如下:
return [
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationTable' => 'migration',
'migrationPath'=>'mongodb_migration',
],
],
];
使用上述配置,每次运行迁移命令时,将使用表backend_migration来记录迁移历史,你无需再在命令行中使用migrationTable选项来定义它。
//配置实例:
D:\phpwork\basic\config\console.php
'controllerMap' => [
'mongodb-migrate' => [
'class' => 'yii\mongodb\console\controllers\MigrateController',
'migrationTable' => 'mongodb_migration',
],
],
命名空间化迁移(Namespaced Migrations)
自2.0.10版本起,你可以使用迁移类的命名空间了,你可以使用migrationNamespaces来定义迁移命名空间列表,为迁移类使用命名空间允许你为迁移使用不同的位置源,例如:
return [
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationNamespaces' => [
'app\migrations', //整个应用的通用配置
'module\migrations', //为特定项目模块的迁移
'some\extension\migrations', //为特定扩展的迁移
],
],
],
];
注意:从不同的命名空间应用的迁移将创建一个单独的迁移历史,因此,你不能只从特定的命名空间应用或恢复迁移。 当操作命名空间的迁移:创建新的,恢复等,你应该在迁移名称前定义命名空间的全称,注意反斜杠()在脚本中通常被视为特殊字符,所以你需要正确定义它以避免脚本错误或不正确的执行,例如:
yii migrate/create 'app\\migrations\\createUserTable'
注意:使用migrationPath定义迁移不能使用命名空间,命名空间化迁移仅可以使用 yii\console\controllers\MigrateController::$migrationNamespaces 进行应用。
独立的迁移(Separated Migrations)
有时,为所有项目迁移使用单一的迁移历史是不可取的。例如,你可以安装'blog'扩展,它包含完全分离的功能,并含有自己的迁移,这些功能不会影响到项目的主要功能。 如果你需要应用几个迁移,并完全独立的追踪它们,你可以配置多个迁移命令,它们使用不同的命名空间和迁移历史表:
return [
'controllerMap' => [
// 整个应用的公共迁移
'migrate-app' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationNamespaces' => ['app\migrations'],
'migrationTable' => 'migration_app',
],
// 为项目特定模块的迁移
'migrate-module' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationNamespaces' => ['module\migrations'],
'migrationTable' => 'migration_module',
],
// 特定扩展的迁移
'migrate-rbac' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationPath' => '@yii/rbac/migrations',
'migrationTable' => 'migration_rbac',
],
],
];
注意现在你同步数据库需要运行多条命令,而不是一条:
yii migrate-app
yii migrate-module
yii migrate-rbac
9、Migrating Multiple Databases(迁移多数据库)
默认情况下,应用到同一个数据库的迁移都由db应用组件来定义,如果你想将它们应用到不同的数据库,你可以定义命令行选项db,格式如下:
yii migrate --db=db2
上述命令会应用迁移到db2数据库。
有时你想要应用一些迁移到一个数据库,另一些应用到另一个数据库,要实现这个目的,需要在实现一个迁移类时,你就明确的指出此迁移需要使用的DB组件的ID,代码如下:
use yii\db\Migration;
class m150101_185401_create_news_table extends Migration
{
public function init()
{
$this->db = 'db2';
parent::init();
}
}
尽管你在命令行选项中指定了一个不同的数据库db,但上述迁移将应用到db2。注意如果在命令行选项中指定了db,那么迁移历史将将记录在db中。 如果你有多个迁移要使用相同的数据库,推荐你使用init()去创建数据库一个基础的迁移类,其他迁移类从此基础类中继承即可。
小贴士:除了设置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。
(全文完)
共 0 条回复
阿江
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276