數(shù)據(jù)庫(kù)遷移(Migrations): 在團(tuán)體開發(fā)中對(duì)你的數(shù)據(jù)庫(kù)使用版本控制

2018-02-24 15:40 更新

數(shù)據(jù)庫(kù)遷移

在開發(fā)和維護(hù)一個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的應(yīng)用程序時(shí),數(shù)據(jù)庫(kù)的結(jié)構(gòu)會(huì)隨代碼的改變而改變。例如,在開發(fā)應(yīng)用程序的過(guò)程中,會(huì)增加一張新表且必須得加進(jìn)來(lái); 在應(yīng)用程序被部署到生產(chǎn)環(huán)境后,需要建立一個(gè)索引來(lái)提高查詢的性能等等。 因?yàn)橐粋€(gè)數(shù)據(jù)庫(kù)結(jié)構(gòu)發(fā)生改變的時(shí)候源代碼也經(jīng)常會(huì)需要做出改變,Yii 提供了一個(gè)?數(shù)據(jù)庫(kù)遷移?功能,該功能可以記錄數(shù)據(jù)庫(kù)的變化, 以便使數(shù)據(jù)庫(kù)和源代碼一起受版本控制。

如下的步驟向我們展示了數(shù)據(jù)庫(kù)遷移工具是如何為開發(fā)團(tuán)隊(duì)所使用的:

  1. Tim 創(chuàng)建了一個(gè)新的遷移對(duì)象(例如,創(chuàng)建一張新的表單,改變字段的定義等)。
  2. Tim 將這個(gè)新的遷移對(duì)象提交到代碼管理系統(tǒng)(例如,Git,Mercurial)。
  3. Doug 從代碼管理系統(tǒng)當(dāng)中更新版本并獲取到這個(gè)新的遷移對(duì)象。
  4. Doug 把這個(gè)遷移對(duì)象提交到本地的開發(fā)數(shù)據(jù)庫(kù)當(dāng)中,這樣一來(lái),Doug 同步了 Tim 所做的修改。

如下的步驟向我們展示了如何發(fā)布一個(gè)附帶數(shù)據(jù)庫(kù)遷移的新版本到生產(chǎn)環(huán)境當(dāng)中:

  1. Scott 為一個(gè)包含數(shù)據(jù)庫(kù)遷移的項(xiàng)目版本創(chuàng)建了一個(gè)發(fā)布標(biāo)簽。
  2. Scott 把發(fā)布標(biāo)簽的源代碼更新到生產(chǎn)環(huán)境的服務(wù)器上。
  3. Scott 把所有的增量數(shù)據(jù)庫(kù)遷移提交到生產(chǎn)環(huán)境數(shù)據(jù)庫(kù)當(dāng)中。

Yii 提供了一整套的遷移命令行工具,通過(guò)這些工具你可以:

  • 創(chuàng)建新的遷移;
  • 提交遷移;
  • 恢復(fù)遷移;
  • 重新提交遷移;
  • 現(xiàn)實(shí)遷移歷史和狀態(tài)。

所有的這些工具都可以通過(guò)?yii migrate?命令來(lái)進(jìn)行操作。 在這一章節(jié),我們將詳細(xì)的介紹如何使用這些工具來(lái)完成各種各樣的任務(wù)。你也可以通過(guò)?yii help migrate?命令來(lái)獲取每一種工具的具體使用方法。

注意:遷移不僅僅只作用于數(shù)據(jù)庫(kù)表,它同樣會(huì)調(diào)整現(xiàn)有的數(shù)據(jù)來(lái)適應(yīng)新的表單、創(chuàng)建 RBAC 分層、又或者是清除緩存。

創(chuàng)建遷移

使用如下命令來(lái)創(chuàng)建一個(gè)新的遷移:

yii migrate/create <name>

必填參數(shù)?name?的作用是對(duì)新的遷移做一個(gè)簡(jiǎn)要的描述。例如,如果這個(gè)遷移是用來(lái)創(chuàng)建一個(gè)叫做?news?的表單的,那么你可以使用create_news_table?這個(gè)名稱并運(yùn)行如下命令:

yii migrate/create create_news_table

注意:因?yàn)?name?參數(shù)會(huì)被用來(lái)生成遷移的類名的一部分,所以該參數(shù)應(yīng)當(dāng)只包含字母、數(shù)字和下劃線。

如上命令將會(huì)在?@app/migrations?目錄下創(chuàng)建一個(gè)新的名為?m150101_185401_create_news_table.php?的 PHP 類文件。該文件包含如下的代碼,它們用來(lái)聲明一個(gè)遷移類?m150101_185401_create_news_table,并附有代碼框架:

<?php

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {
    }

    public function down()
    {
        echo "m101129_185401_create_news_table cannot be reverted.\n";
        return false;
    }
}

每個(gè)數(shù)據(jù)庫(kù)遷移都會(huì)被定義為一個(gè)繼承自 yii\db\Migration 的 PHP 類。類的名稱按照?m<YYMMDD_HHMMSS>_<Name>?的格式自動(dòng)生成,其中

  • <YYMMDD_HHMMSS>?指執(zhí)行創(chuàng)建遷移命令的 UTC 時(shí)間。
  • <Name>?和你執(zhí)行命令時(shí)所帶的?name?參數(shù)值相同。

在遷移類當(dāng)中,你應(yīng)當(dāng)在?up()?方法中編寫改變數(shù)據(jù)庫(kù)結(jié)構(gòu)的代碼。你可能還需要在?down()?方法中編寫代碼來(lái)恢復(fù)由?up()?方法所做的改變。 當(dāng)你通過(guò) migration 升級(jí)數(shù)據(jù)庫(kù)時(shí),?up()?方法將會(huì)被調(diào)用,反之,?down()?將會(huì)被調(diào)用。如下代碼展示了如何通過(guò)遷移類來(lái)創(chuàng)建一張?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');
    }

}

注意:并不是所有遷移都是可恢復(fù)的。例如,如果?up()?方法刪除了表中的一行數(shù)據(jù),這將無(wú)法通過(guò)?down()?方法來(lái)恢復(fù)這條數(shù)據(jù)。有時(shí)候,你也許只是懶得去執(zhí)行?down()?方法了,因?yàn)樗诨謴?fù)數(shù)據(jù)庫(kù)遷移方面并不是那么的通用。在這種情況下,你應(yīng)當(dāng)在?down()?方法中返回?false?來(lái)表明這個(gè) migration 是無(wú)法恢復(fù)的。

migration 的基類 yii\db\Migration 通過(guò) yii\db\Migration::db 屬性來(lái)連接了數(shù)據(jù)庫(kù)。你可以通過(guò)?配合數(shù)據(jù)庫(kù)工作?章節(jié)中所描述的那些方法來(lái)操作數(shù)據(jù)庫(kù)表。

當(dāng)你通過(guò) migration 創(chuàng)建一張表或者字段的時(shí)候,你應(yīng)該使用?抽象類型?而不是?實(shí)體類型,這樣一來(lái)你的遷移對(duì)象就可以從特定的 DBMS 當(dāng)中抽離出來(lái)。 yii\db\Schema 類定義了一整套可用的抽象類型常量。這些常量的格式為?TYPE_<Name>。例如,TYPE_PK?指代自增主鍵類型;TYPE_STRING?指代字符串類型。 當(dāng)遷移對(duì)象被提交到某個(gè)特定的數(shù)據(jù)庫(kù)的時(shí)候,這些抽象類型將會(huì)被轉(zhuǎn)換成相對(duì)應(yīng)的實(shí)體類型。以 MySQL 為例,TYPE_PK?將會(huì)變成?int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, 而?TYPE_STRING?則變成varchar(255)

在使用抽象類型的時(shí)候,你可以添加額外的約束條件。在上面的例子當(dāng)中,?NOT NULL?被添加到?Schema::TYPE_STRING?當(dāng)中來(lái)指定該字段不能為空。

提示:抽象類型和實(shí)體類型之間的映射關(guān)系是由每個(gè)具體的?QueryBuilder?類當(dāng)中的 yii\db\QueryBuilder::$typeMap 屬性所指定的。

從 2.0.5 的版本開始,schema 構(gòu)造器提供了更加方便的方法來(lái)定義字段,因此上面的 migration 可以被改寫成:

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::primaryKey(),
            'title' => Schema::string()->notNull(),
            'content' => Schema::text(),
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }

}

事務(wù)遷移

當(dāng)需要實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)庫(kù)遷移的時(shí)候,確定每一個(gè)遷移的執(zhí)行是否成功或失敗就變得相當(dāng)重要了,因?yàn)檫@將影響到數(shù)據(jù)庫(kù)的完整性和一致性。為了達(dá)到這個(gè)目標(biāo),我們建議你把每個(gè)遷移里面的數(shù)據(jù)庫(kù)操作都封裝到一個(gè)?transaction?里面。

實(shí)現(xiàn)事務(wù)遷移的一個(gè)更為簡(jiǎn)便的方法是把遷移的代碼都放到?safeUp()?和?safeDown()?方法里面。它們與?up()?和?down()?的不同點(diǎn)就在于它們是被隱式的封裝到事務(wù)當(dāng)中的。如此一來(lái),只要這些方法里面的任何一個(gè)操作失敗了,那么所有之前的操作都會(huì)被自動(dòng)的回滾。

在如下的例子當(dāng)中,除了創(chuàng)建?news?表以外,我們還插入了一行初始化數(shù)據(jù)到表里面。

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function safeUp()
    {
        $this->createTable('news', [
            'id' => Schema::primaryKey(),,
            'title' => Schema::string()->notNull(),
            'content' => Schema::text(),
        ]);

        $this->insert('news', [
            'title' => 'test 1',
            'content' => 'content 1',
        ]);
    }

    public function safeDown()
    {
        $this->delete('news', ['id' => 1]);
        $this->dropTable('news');
    }
}

需要注意的是,當(dāng)你在?safeUp()?當(dāng)中執(zhí)行多個(gè)數(shù)據(jù)庫(kù)操作的時(shí)候,你應(yīng)該在?safeDown()?方法當(dāng)中反轉(zhuǎn)它們的執(zhí)行順序。在上面的例子當(dāng)中,我們?cè)?safeUp()?方法當(dāng)中首先創(chuàng)建了一張表,然后插入了一條數(shù)據(jù);而在?safeDown()?方法當(dāng)中,我們首先刪除那一行數(shù)據(jù),然后才刪除那張表。

注意:并不是所有的數(shù)據(jù)庫(kù)都支持事務(wù)。有些數(shù)據(jù)庫(kù)查詢也是不能被放倒事務(wù)里面的。在?implicit commit?章節(jié)當(dāng)中有相關(guān)的例子可以參考。如果遇到這種情況的話,那么你應(yīng)該使用?up()?和?down()?方法進(jìn)行替代。

訪問(wèn)數(shù)據(jù)庫(kù)的方法

遷移的基類 yii\db\Migration 提供了一整套訪問(wèn)和操作數(shù)據(jù)庫(kù)的方法。你可能會(huì)發(fā)現(xiàn)這些方法的命名和 yii\db\Command 類提供的?DAO 方法?很類似。 例如,yii\db\Migration::createTable() 方法可以創(chuàng)建一張新的表,這和 yii\db\Command::createTable() 的功能是一模一樣的。

使用 yii\db\Migration 所提供的方法的好處在于你不需要再顯式的創(chuàng)建 yii\db\Command 實(shí)例,而且在執(zhí)行每個(gè)方法的時(shí)候都會(huì)顯示一些有用的信息來(lái)告訴我們數(shù)據(jù)庫(kù)操作是不是都已經(jīng)完成,還有它們完成這些操作花了多長(zhǎng)時(shí)間等等。

如下是所有這些數(shù)據(jù)庫(kù)訪問(wèn)方法的列表:

  • yii\db\Migration::execute(): 執(zhí)行一條 SQL 語(yǔ)句
  • yii\db\Migration::insert(): 插入單行數(shù)據(jù)
  • yii\db\Migration::batchInsert(): 插入多行數(shù)據(jù)
  • yii\db\Migration::update(): 更新數(shù)據(jù)
  • yii\db\Migration::delete(): 刪除數(shù)據(jù)
  • yii\db\Migration::createTable(): 創(chuàng)建表
  • yii\db\Migration::renameTable(): 重命名表名
  • yii\db\Migration::dropTable(): 刪除一張表
  • yii\db\Migration::truncateTable(): 清空表中的所有數(shù)據(jù)
  • yii\db\Migration::addColumn(): 加一個(gè)字段
  • yii\db\Migration::renameColumn(): 重命名字段名稱
  • yii\db\Migration::dropColumn(): 刪除一個(gè)字段
  • yii\db\Migration::alterColumn(): 修改字段
  • yii\db\Migration::addPrimaryKey(): 添加一個(gè)主鍵
  • yii\db\Migration::dropPrimaryKey(): 刪除一個(gè)主鍵
  • yii\db\Migration::addForeignKey(): 添加一個(gè)外鍵
  • yii\db\Migration::dropForeignKey(): 刪除一個(gè)外鍵
  • yii\db\Migration::createIndex(): 創(chuàng)建一個(gè)索引
  • yii\db\Migration::dropIndex(): 刪除一個(gè)索引

提示:yii\db\Migration 并沒有提供數(shù)據(jù)庫(kù)的查詢方法。這是因?yàn)橥ǔD闶遣恍枰?shù)據(jù)庫(kù)把數(shù)據(jù)一行一行查出來(lái)再顯示出來(lái)的。另外一個(gè)原因是你完全可以使用強(qiáng)大的?Query Builder 查詢構(gòu)建器?來(lái)構(gòu)建和查詢。

提交遷移

為了將數(shù)據(jù)庫(kù)升級(jí)到最新的結(jié)構(gòu),你應(yīng)該使用如下命令來(lái)提交所有新的遷移:

yii migrate

這條命令會(huì)列出迄今為止所有未提交的遷移。如果你確定你需要提交這些遷移,它將會(huì)按照類名當(dāng)中的時(shí)間戳的順序,一個(gè)接著一個(gè)的運(yùn)行每個(gè)新的遷移類里面的?up()?或者是?safeUp()?方法。如果其中任意一個(gè)遷移提交失敗了,那么這條命令將會(huì)退出并停止剩下的那些還未執(zhí)行的遷移。

對(duì)于每一個(gè)成功提交的遷移,這條命令都會(huì)在一個(gè)叫做?migration?的數(shù)據(jù)庫(kù)表中插入一條包含應(yīng)用程序成功提交遷移的記錄,該記錄將幫助遷移工具判斷哪些遷移已經(jīng)提交, 哪些還沒有提交。

提示:遷移工具將會(huì)自動(dòng)在數(shù)據(jù)庫(kù)當(dāng)中創(chuàng)建?migration?表,該數(shù)據(jù)庫(kù)是在該命令的 yii\console\controllers\MigrateController::db 選項(xiàng)當(dāng)中指定的。默認(rèn)情況下,是由?db?application component?指定的。

有時(shí),你可能只需要提交一個(gè)或者少數(shù)的幾個(gè)遷移,你可以使用該命令指定需要執(zhí)行的條數(shù),而不是執(zhí)行所有的可用遷移。例如,如下命令將會(huì)嘗試提交前三個(gè)可用的遷移:

yii migrate 3

你也可以指定一個(gè)特定的遷移,按照如下格式使用?migrate/to?命令來(lái)指定數(shù)據(jù)庫(kù)應(yīng)該提交哪一個(gè)遷移:

yii migrate/to 150101_185401                      # using timestamp to specify the migration 使用時(shí)間戳來(lái)指定遷移
yii migrate/to "2015-01-01 18:54:01"              # using a string that can be parsed by strtotime() 使用一個(gè)可以被 strtotime() 解析的字符串
yii migrate/to m150101_185401_create_news_table   # using full name 使用全名
yii migrate/to 1392853618                         # using UNIX timestamp 使用 UNIX 時(shí)間戳

如果在指定要提交的遷移前面還有未提交的遷移,那么在執(zhí)行這個(gè)被指定的遷移之前,這些還未提交的遷移會(huì)先被提交。

如果被指定提交的遷移在之前已經(jīng)被提交過(guò),那么在其之后的那些遷移將會(huì)被還原。

還原遷移

你可以使用如下命令來(lái)還原其中一個(gè)或多個(gè)意見被提交過(guò)的遷移:

yii migrate/down     # revert the most recently applied migration 還原最近一次提交的遷移
yii migrate/down 3   # revert the most 3 recently applied migrations 還原最近三次提交的遷移

注意:并不是所有的遷移都能被還原。嘗試還原這類遷移將可能導(dǎo)致報(bào)錯(cuò)甚至是終止所有的還原進(jìn)程。

重做遷移

重做遷移的意思是先還原指定的遷移,然后再次提交。如下所示:

yii migrate/redo        # redo the last applied migration 重做最近一次提交的遷移
yii migrate/redo 3      # redo the last 3 applied migrations 重做最近三次提交的遷移

注意:如果一個(gè)遷移是不能被還原的,那么你將無(wú)法對(duì)它進(jìn)行重做。

列出遷移

你可以使用如下命令列出那些提交了的或者是還未提交的遷移:

yii migrate/history     # 顯示最近10次提交的遷移
yii migrate/history 5   # 顯示最近5次提交的遷移
yii migrate/history all # 顯示所有已經(jīng)提交過(guò)的遷移

yii migrate/new         # 顯示前10個(gè)還未提交的遷移
yii migrate/new 5       # 顯示前5個(gè)還未提交的遷移
yii migrate/new all     # 顯示所有還未提交的遷移

修改遷移歷史

有時(shí)候你也許需要簡(jiǎn)單的標(biāo)記一下你的數(shù)據(jù)庫(kù)已經(jīng)升級(jí)到一個(gè)特定的遷移,而不是實(shí)際提交或者是還原遷移。這個(gè)經(jīng)常會(huì)發(fā)生在你手動(dòng)的改變數(shù)據(jù)庫(kù)的一個(gè)特定狀態(tài),而又不想相應(yīng)的遷移被重復(fù)提交。那么你可以使用如下命令來(lái)達(dá)到目的:

yii migrate/mark 150101_185401                      # 使用時(shí)間戳來(lái)指定遷移
yii migrate/mark "2015-01-01 18:54:01"              # 使用一個(gè)可以被 strtotime() 解析的字符串
yii migrate/mark m150101_185401_create_news_table   # 使用全名
yii migrate/mark 1392853618                         # 使用 UNIX 時(shí)間戳

該命令將會(huì)添加或者刪除?migration?表當(dāng)中的某幾行數(shù)據(jù)來(lái)表明數(shù)據(jù)庫(kù)已經(jīng)提交到了指定的某個(gè)遷移上。執(zhí)行這條命令期間不會(huì)有任何的遷移會(huì)被提交或還原。

自定義遷移

有很多方法可以自定義遷移命令。

使用命令行選項(xiàng)

遷移命令附帶了幾個(gè)命令行選項(xiàng),可以用來(lái)自定義它的行為:

  • interactive: boolean (默認(rèn)值為 true),指定是否以交互模式來(lái)運(yùn)行遷移。當(dāng)被設(shè)置為 true 時(shí),在命令執(zhí)行某些操作前,會(huì)提示用戶。如果你希望在后臺(tái)執(zhí)行該命令,那么你應(yīng)該把它設(shè)置成 false。

  • migrationPath: string (默認(rèn)值為?@app/migrations),指定存放所有遷移類文件的目錄。該選項(xiàng)可以是一個(gè)目錄的路徑,也可以是?路徑別名。需要注意的是指定的目錄必選存在,否則將會(huì)觸發(fā)一個(gè)錯(cuò)誤。

  • migrationTable: string (默認(rèn)值為?migration),指定用于存儲(chǔ)遷移歷史信息的數(shù)據(jù)庫(kù)表名稱。如果這張表不存在,那么遷移命令將自動(dòng)創(chuàng)建這張表。當(dāng)然你也可以使用這樣的字段結(jié)構(gòu):?version varchar(255) primary key, apply_time integer?來(lái)手動(dòng)創(chuàng)建這張表。

  • db: string (默認(rèn)值為?db),指定數(shù)據(jù)庫(kù)?application component?的 ID。它指的是將會(huì)被該命令遷移的數(shù)據(jù)庫(kù)。

  • templateFile: string (defaults to?@yii/views/migration.php),指定生產(chǎn)遷移框架代碼類文件的模版文件路徑。該選項(xiàng)即可以使用文件路徑來(lái)指定,也可以使用路徑?別名?來(lái)指定。該模版文件是一個(gè)可以使用預(yù)定義變量?$className?來(lái)獲取遷移類名稱的 PHP 腳本。

如下例子向我們展示了如何使用這些選項(xiàng):

例如,如果我們需要遷移一個(gè)?forum?模塊,而該遷移文件放在該模塊下的?migrations?目錄當(dāng)中,那么我們可以使用如下命令:

# 在 forum 模塊中以非交互模式進(jìn)行遷移
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0

全局配置命令

在運(yùn)行遷移命令的時(shí)候每次都要重復(fù)的輸入一些同樣的參數(shù)會(huì)很煩人,這時(shí)候,你可以選擇在應(yīng)用程序配置當(dāng)中進(jìn)行全局配置,一勞永逸:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];

如上所示配置,在每次運(yùn)行遷移命令的時(shí)候,backend_migration?表將會(huì)被用來(lái)記錄遷移歷史。你再也不需要通過(guò)migrationTable?命令行參數(shù)來(lái)指定這張歷史紀(jì)錄表了。

遷移多個(gè)數(shù)據(jù)庫(kù)

默認(rèn)情況下,遷移將會(huì)提交到由?db?application component?所定義的同一個(gè)數(shù)據(jù)庫(kù)當(dāng)中。如果你需要提交到不同的數(shù)據(jù)庫(kù),你可以像下面那樣指定?db?命令行選項(xiàng),

yii migrate --db=db2

上面的命令將會(huì)把遷移提交到?db2?數(shù)據(jù)庫(kù)當(dāng)中。

偶爾有限時(shí)候你需要提交?一些?遷移到一個(gè)數(shù)據(jù)庫(kù),而另外一些則提交到另一個(gè)數(shù)據(jù)庫(kù)。為了達(dá)到這個(gè)目的,你應(yīng)該在實(shí)現(xiàn)一個(gè)遷移類的時(shí)候指定需要用到的數(shù)據(jù)庫(kù)組件的 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?命令行選項(xiàng)指定了另外一個(gè)不同的數(shù)據(jù)庫(kù),上面的遷移還是會(huì)被提交到?db2?當(dāng)中。需要注意的是這個(gè)時(shí)候遷移的歷史信息依然會(huì)被記錄到?db?命令行選項(xiàng)所指定的數(shù)據(jù)庫(kù)當(dāng)中。

如果有多個(gè)遷移都使用到了同一個(gè)數(shù)據(jù)庫(kù),那么建議你創(chuàng)建一個(gè)遷移的基類,里面包含上述的?init()?代碼。然后每個(gè)遷移類都繼承這個(gè)基類就可以了。

提示:除了在 yii\db\Migration::db 參數(shù)當(dāng)中進(jìn)行設(shè)置以外,你還可以通過(guò)在遷移類中創(chuàng)建新的數(shù)據(jù)庫(kù)連接來(lái)操作不同的數(shù)據(jù)庫(kù)。然后通過(guò)這些連接再使用?DAO 方法?來(lái)操作不同的數(shù)據(jù)庫(kù)。

另外一個(gè)可以讓你遷移多個(gè)數(shù)據(jù)庫(kù)的策略是把遷移存放到不同的目錄下,然后你可以通過(guò)如下命令分別對(duì)不同的數(shù)據(jù)庫(kù)進(jìn)行遷移:

yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...

第一條命令將會(huì)把?@app/migrations/db1?目錄下的遷移提交到?db1?數(shù)據(jù)庫(kù)當(dāng)中,第二條命令則會(huì)把?@app/migrations/db2?下的遷移提交到?db2?數(shù)據(jù)庫(kù)當(dāng)中,以此類推。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)