本文講述了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,並附有代碼架構:
<?phpuse 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)'); }}}
每個資料庫遷移都會被定義為一個繼承自 yii\db\Migration 的 PHP 類。類的名稱按照 m<YYMMDD_HHMMSS>_<Name> 的格式自動產生,其中
<YYMMDD_HHMMSS> 指執行建立遷移命令的 UTC 時間。
<Name> 和你執行命令時所帶的 name 參數值相同。
在遷移類當中,你應當在 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 是無法恢複的。
訪問資料庫的方法
遷移的基類 yii\db\Migration 提供了一整套訪問和操作資料庫的方法。你可能會發現這些方法的命名和 yii\db\Command 類提供的 DAO 方法很類似。 例如,yii\db\Migration::createTable() 方法可以建立一張新的表,這和 yii\db\Command::createTable() 的功能是一模一樣的。
使用 yii\db\Migration 所提供的方法的好處在於你不需要再顯式的建立 yii\db\Command 執行個體,而且在執行每個方法的時候都會顯示一些有用的資訊來告訴我們資料庫操作是不是都已經完成,還有它們完成這些操作花了多長時間等等。
如下是所有這些資料庫存取方法的列表:
yii\db\Migration::execute(): 執行一條 SQL 陳述式
yii\db\Migration::insert(): 插入單行資料
yii\db\Migration::batchInsert(): 插入多行資料
yii\db\Migration::update(): 更新資料
yii\db\Migration::delete(): 刪除資料
yii\db\Migration::createTable(): 建立表
yii\db\Migration::renameTable(): 重新命名表名
yii\db\Migration::dropTable(): 刪除一張表
yii\db\Migration::truncateTable(): 清空表中的所有資料
yii\db\Migration::addColumn(): 加一個欄位
yii\db\Migration::renameColumn(): 重新命名欄位名稱
yii\db\Migration::dropColumn(): 刪除一個欄位
yii\db\Migration::alterColumn(): 修改欄位
yii\db\Migration::addPrimaryKey(): 添加一個主鍵
yii\db\Migration::dropPrimaryKey(): 刪除一個主鍵
yii\db\Migration::addForeignKey(): 添加一個外鍵
yii\db\Migration::dropForeignKey(): 刪除一個外鍵
yii\db\Migration::createIndex(): 建立一個索引
yii\db\Migration::dropIndex(): 刪除一個索引
提交遷移
為了將資料庫升級到最新的結構,你應該使用如下命令來提交所有新的遷移:
這條命令會列出迄今為止所有未提交的遷移。如果你確定你需要提交這些遷移,它將會按照類名當中的時間戳記的順序,一個接著一個的運行每個新的遷移類裡面的 up() 或者是 safeUp() 方法。如果其中任意一個遷移提交失敗了,那麼這條命令將會退出並停止剩下的那些還未執行的遷移。
對於每一個成功提交的遷移,這條命令都會在一個叫做 migration 的資料庫表中插入一條包含應用程式成功提交遷移的記錄,該記錄將協助遷移工具判斷哪些遷移已經提交, 哪些還沒有提交。
提示:遷移工具將會自動在資料庫當中建立 migration 表,該資料庫是在該命令的 yii\console\controllers\MigrateController::db 選項當中指定的。預設情況下,是由 db application component 指定的。
有時,你可能只需要提交一個或者少數的幾個遷移,你可以使用該命令指定需要執行的條數,而不是執行所有的可用遷移。例如,如下命令將會嘗試提交前三個可用的遷移:
你也可以指定一個特定的遷移,按照如下格式使用 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 命令列選項,
上面的命令將會把遷移提交到 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=db1yii migrate --migrationPath=@app/migrations/db2 --db=db2...
第一條命令將會把 @app/migrations/db1 目錄下的遷移提交到 db1 資料庫當中,第二條命令則會把 @app/migrations/db2 下的遷移提交到 db2 資料庫當中,以此類推。
更多關於Yii相關內容感興趣的讀者可查看本站專題:《Yii架構入門及常用技巧總結》、《php優秀開發架構總結》、《smarty模板入門基礎教程》、《php物件導向程式設計入門教程》、《php字串(string)用法總結》、《php+mysql資料庫操作入門教程》及《php常見資料庫操作技巧匯總》
希望本文所述對大家基於Yii架構的PHP程式設計有所協助。