本文講述了yii2.0資料庫遷移的方法。分享給大家供大家參考,如下:
創建遷移
使用以下命令來創建一個新的遷移:
yii migrate/create <name>
必填參數 name 的作用是對新的遷移做一個簡要的描述。例如,如果這個遷移是用來往多個資料庫同一張表 ( 假設每個資料庫都有news表) 新增欄位的,那麼你可以使用addColumn_news (這個名稱自訂)這個名稱並執行以下指令:
yii migrate/create addColumn_news
注意:因為name 參數會被用來產生遷移的類別名稱的一部分,所以該參數應只包含字母、數字和底線。
如上指令將會在 @app/migrations 目錄下建立一個新的名為 m150101_185401_addColumn_news.php 的 PHP 類別檔案。該檔案包含如下的程式碼,它們用來宣告一個遷移類別 m150101_185401_addColumn_news,並附有程式碼框架:
<?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['db']; 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('{{%news}}','name','varchar(20)'); $this->addColumn('{{%news}}','nickname','varchar(20)'); $this->addColumn('{{%news}}','age','int(3)'); $this->addColumn('{{%news}}','sex','int(1)'); $this->addColumn('{{%news}}','site_id','int(5)'); } } //down() 该方法与up()方法相反,是删除字段的意思 public function down() { $dbs = $this->createDbs(); foreach($dbs as $v){ $this->db=$v; $this->dropColumn('{{%news}}','name','varchar(20)'); $this->dropColumn('{{%news}}','nickname','varchar(20)'); $this->dropColumn('{{%news}}','age','int(3)'); $this->dropColumn('{{%news}}','sex','int(1)'); $this->dropColumn('{{%news}}','site_id','int(5)'); } } }
每個資料庫遷移被定義為繼承自一個繼承自一個類別的名稱依照 m
在遷移類別當中,你應在 up() 方法中寫出改變資料庫結構的程式碼。你可能還需要在 down() 方法中寫程式碼來恢復 up() 方法所做的改變。 當你透過 migration 升級資料庫時, up() 方法將會被調用,反之, down() 將會被調用。如下程式碼展示如何透過遷移類別來建立一張 news 表:
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'); } }
注意:並不是所有遷移都是可恢復的。例如,如果 up() 方法刪除了表中的一行數據,這將無法透過 down() 方法來恢復這條數據。有時候,你也許只是懶得去執行 down() 方法了,因為它在恢復資料庫遷移方面並不是那麼的通用。在這種情況下,你應在down() 方法中傳回 false 來表示這個 migration 是無法恢復的。
存取資料庫的方法
遷移的基類 yiidbMigration 提供了一整套存取和操作資料庫的方法。你可能會發現這些方法的命名和 yiidbCommand 類別提供的 DAO 方法很類似。 例如,yiidbMigration::createTable() 方法可以建立一張新的表,這和 yiidbCommand::createTable() 的功能是一模一樣的。
使用yiidbMigration 所提供的方法的好處在於你不需要再明確的創建yiidbCommand 實例,而且在執行每個方法的時候都會顯示一些有用的信息來告訴我們數據庫操作是不是都已經完成,還有它們完成這些操作花了多長時間等等。
如下是所有這些資料庫存取方法的清單:
yiidbMigration::execute(): 執行一條SQL 語句
yiidbMigration::insert(): 插入單行資料
yiidbMigration::batchInsertInsert(): 插入多行資料::update(): 更新資料
yiidbMigration::delete(): 刪除資料
yiidbMigration::createTable(): 建立表格
yiidbMigration::renameTable(): 重新命名表名
yiidbMigration::dropTable(): 刪除一個符號張表
yiidbMigration::truncateTable(): 清空表中的所有資料
yiidbMigration::addColumn(): 加一個欄位
yiidbMigration::renameColumn():Column個欄位名稱
yiidbMigration::dropumn(ig):
yiidbMigration::alterColumn(): 修改欄位
yiidbMigration::addPrimaryKey(): 新增一個主鍵
yiidbMigration::dropPrimaryKey(): 刪除一個主鍵
yiidbMigration::ForeignKey(): 新增一個外鍵): 刪除一個外鍵
yiidbMigration::createIndex(): 建立一個索引
yiidbMigration::dropIndex(): 刪除一個索引
提交遷移
為了將資料庫升級到最新的命令,你應該使用以下命令來提交所有新的遷移:
yii migrate
這條指令會列出迄今為止所有未提交的遷移。如果你確定你需要提交這些遷移,它將會按照類別名稱當中的時間戳記的順序,一個接著一個的運行每個新的遷移類別裡面的 up() 或是 safeUp() 方法。如果其中任意一個遷移提交失敗了,那麼這條命令將會退出並停止剩下的那些還未執行的遷移。
對於每一個成功提交的遷移,這條命令都會在一個叫做 migration 的資料庫表中插入一條包含應用程式成功提交遷移的記錄,該記錄將幫助遷移工具判斷哪些遷移已經提交, 哪些還沒有提交。
提示:遷移工具將會自動在資料庫當中建立 migration 表,該資料庫是在該指令的 yiiconsolecontrollersMigrateController::db 選項中指定的。預設情況下,是由 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 [ 'controllerMap' => [ 'migrate' => [ 'class' => 'yii\console\controllers\MigrateController', 'migrationTable' => 'backend_migration', ], ], ];
如上所示配置,在每次运行迁移命令的时候,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 = 'db2'; 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中文网!