ホームページ > php教程 > PHP开发 > yii2.0 データベース移行チュートリアル

yii2.0 データベース移行チュートリアル

高洛峰
リリース: 2016-12-20 16:30:32
オリジナル
1134 人が閲覧しました

この記事では、yii2.0データベースの移行方法について説明します。参考までに皆さんと共有してください。詳細は次のとおりです:

移行を作成します

次のコマンドを使用して新しい移行を作成します:

yii migrate/create <name>
ログイン後にコピー

必須パラメータ名の役割は、概要を与えることです。新しい移行の説明。たとえば、この移行を使用して複数のデータベースの同じテーブルにフィールドを追加する場合 (各データベースにニュース テーブルがあると仮定)、名前 addColumn_news (名前はカスタマイズされます) を使用して、次のコマンドを実行できます:

yii migrate/create addColumn_news
ログイン後にコピー

注: name パラメーターは移行されたクラス名の一部を生成するために使用されるため、このパラメーターには文字、数字、アンダースコアのみを含める必要があります。

上記のコマンドは、m150101_185401_addColumn_news.php という名前の新しい PHP クラス ファイルを @app/migrations ディレクトリに作成します。このファイルには、コード スケルトンとともに移行クラス 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[&#39;db&#39;];
  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(&#39;{{%news}}&#39;,&#39;name&#39;,&#39;varchar(20)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;nickname&#39;,&#39;varchar(20)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;age&#39;,&#39;int(3)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;sex&#39;,&#39;int(1)&#39;);
    $this->addColumn(&#39;{{%news}}&#39;,&#39;site_id&#39;,&#39;int(5)&#39;);
  }
}
//down()  该方法与up()方法相反,是删除字段的意思
public function down()
{
  $dbs = $this->createDbs();
  foreach($dbs as $v){
    $this->db=$v;
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;name&#39;,&#39;varchar(20)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;nickname&#39;,&#39;varchar(20)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;age&#39;,&#39;int(3)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;sex&#39;,&#39;int(1)&#39;);
    $this->dropColumn(&#39;{{%news}}&#39;,&#39;site_id&#39;,&#39;int(5)&#39;);
  }
}
}
ログイン後にコピー

各データベース移行は、yiidbMigration から継承された PHP クラスとして定義されます。クラスの名前は、m_ の形式で自動的に生成されます。ここで、

は、移行作成コマンドが実行されるときの UTC 時間を指します。

はコマンド実行時の name パラメータの値と同じです。

移行クラスでは、up() メソッドでデータベース構造を変更するコードを記述する必要があります。 up() メソッドによって行われた変更を元に戻すために、down() メソッドにコードを記述する必要がある場合もあります。 移行によってデータベースをアップグレードすると、up() メソッドが呼び出され、その逆の場合は down() メソッドが呼び出されます。次のコードは、移行クラスを通じてニュース テーブルを作成する方法を示しています。

use yii\db\Schema;
use yii\db\Migration;
class m150101_185401_create_news_table extends \yii\db\Migration
{
  public function up()
  {
    $this->createTable(&#39;news&#39;, [
      &#39;id&#39; => Schema::TYPE_PK,
      &#39;title&#39; => Schema::TYPE_STRING . &#39; NOT NULL&#39;,
      &#39;content&#39; => Schema::TYPE_TEXT,
    ]);
  }
  public function down()
  {
    $this->dropTable(&#39;news&#39;);
  }
}
ログイン後にコピー

注: すべての移行が元に戻せるわけではありません。たとえば、up() メソッドがテーブル内のデータ行を削除した場合、このデータは down() メソッドでは復元できません。場合によっては、データベース移行を元に戻すのにそれほど汎用性が高くないために、 down() メソッドを実行するのが面倒な場合があります。この場合、移行が元に戻せないことを示すために、 down() メソッドで false を返す必要があります。

データベースにアクセスするためのメソッド

移行基本クラス yiidbMigration は、データベースにアクセスして操作するためのメソッドの完全なセットを提供します。これらのメソッドの名前は、yiidbCommand クラスによって提供される DAO メソッドに似ていることがわかります。 たとえば、 yiidbMigration::createTable() メソッドは、yiidbCommand::createTable() と同じ機能を持つ新しいテーブルを作成できます。

yiidbMigration によって提供されるメソッドを使用する利点は、yiidbCommand インスタンスを明示的に作成する必要がなくなり、各メソッドの実行時に、データベース操作が完了したかどうか、およびその内容を示すいくつかの有用な情報が表示されることです。これらの操作を完了するまでに時間がかかったなど。

以下は、これらすべてのデータベース アクセス方法のリストです:

yiidbMigration::execute(): SQL ステートメントを実行します
yiidbMigration::insert(): 単一行のデータを挿入します
yiidbMigration::batchInsert(): 挿入複数行のデータ
yiidbMigration::update(): データを更新
yiidbMigration::delete(): データを削除
yiidbMigration::createTable(): テーブルを作成
yiidbMigration::renameTable(): テーブル名の変更
yiidbMigration::dropTable (): テーブルを 1 つ削除
yiidbMigration::truncateTable(): テーブル内のデータをすべてクリア
yiidbMigration::addColumn(): フィールドを追加
yiidbMigration::renameColumn(): フィールド名を変更
yiidbMigration::dropColumn() : フィールドを削除します
yiidbMigration::alterColumn(): フィールドを変更します
yiidbMigration::addPrimaryKey(): 主キーを追加します
yiidbMigration::dropPrimaryKey(): 主キーを削除します
yiidbMigration::addForeignKey(): 外部キーを追加しますkey
yiidbMigration::dropForeignKey(): 外部キーを削除する
yiidbMigration::createIndex(): インデックスを作成する
yiidbMigration::dropIndex(): インデックスを削除する

移行を送信する

データベースを最新のものにアップグレードするにはこの構造では、次のコマンドを使用してすべての新しい移行を送信する必要があります:

yii migrate
ログイン後にコピー

このコマンドは、これまでにコミットされていないすべての移行を一覧表示します。これらの移行を送信する必要があると判断した場合、新しい各移行クラスで up() メソッドまたはsafeUp() メソッドがクラス名のタイムスタンプの順に順番に実行されます。いずれかの移行がコミットに失敗した場合、このコマンドは終了し、まだ実行されていない残りの移行を停止します。

このコマンドは、正常に送信された移行ごとに、アプリケーションの正常に送信された移行を含むレコードを、移行と呼ばれるデータベース テーブルに挿入します。このレコードは、移行ツールがどの移行が送信され、どの移行が送信されていないかを判断するのに役立ちます。

ヒント: 移行ツールは、コマンドの yiiconsolecontrollersMigrateController::db オプションで指定されたデータベースに移行テーブルを自動的に作成します。デフォルトでは、db アプリケーション コンポーネントによって指定されます。

有时,你可能只需要提交一个或者少数的几个迁移,你可以使用该命令指定需要执行的条数,而不是执行所有的可用迁移。例如,如下命令将会尝试提交前三个可用的迁移:

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 [
  &#39;controllerMap&#39; => [
    &#39;migrate&#39; => [
      &#39;class&#39; => &#39;yii\console\controllers\MigrateController&#39;,
      &#39;migrationTable&#39; => &#39;backend_migration&#39;,
    ],
  ],
];
ログイン後にコピー

如上所示配置,在每次运行迁移命令的时候,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 = &#39;db2&#39;;
    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中文网!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート