データーベースのマイグレーション

:データーベースのマイグレーションは、v3.4.0からの機能です。 また、現在は、MySqlのみのサポートです。

目次

はじめに

データベースを利用したアプリケーションを開発し保守していると、ソースコードと同じように、データベースの構造も徐々に進化していきます。 例えば開発中に、新しいカラムやテーブルを追加したり、 仕様変更によって、制約が変わるかも知れません。

また、アプリケーションが運用段階に入った後で、インデックスを追加する必要があることに気付くかも知れません。 このようなデータベースの構造変更 (マイグレーション) の経過を記録し管理することは、ソースコードの変更を記録するのと同じように、非常に重要なことです。 ソースコードとデータベースの同期が崩れた場合には、全体のシステムが壊れる可能性が非常に大きいのです。 こういう理由から、Envi はデータベースマイグレーションツールを提供して、データベースマイグレーションの履歴を管理し、新しいマイグレーションを適用したり、既存のマイグレーションを破棄したりすることを可能にしています。

マイグレーションクラス内で利用できるメソッド

通常テーブルを新規に作成するには必要なSQL文を直接実行して作成します。 カラムを追加したりする場合も同じです。

それに対してマイグレーションを使う場合は、テーブルを新規に作成するためのマイグレーションスクリプトと呼ばれるスクリプトファイルを作成し実行します。

後からカラムを追加したい場合には、カラムを追加するための別のスクリプトファイルを作成し実行します。

詳しくは、 クラスリファレンス:DB/Migration

を参照して下さい。

マイグレーションを作成する

新しいマイグレーションを作成するためには、下記のコマンドを実行します。

envi init-migration <{app key}> <{マイグレーション名}>

要求される {マイグレーション名} パラメータには、マイグレーションの非常に短い説明 (例えば create_news_table) を指定します。 後述するように、この name パラメータは PHP のクラス名の一部として使用されます。 したがって、アルファベット、数字、および/または、アンダースコアだけで構成し、過去のマイグレーションとは違う名前にする必要があります。

envi init-migration bbs bbs_users_add

上記のコマンドは、db/migrate/ ディレクトリに、bbs_20141011114106_bbs_users_add.php という名前の新しいファイルを作成します。 (20141011114106はコマンドの実行時間が入る) このファイルは初期状態では以下の内容を含んでいます。


<?php
class bbs_20141011114106_bbs_users_add extends EnviMigrationBase
{


    public function 
__construct()
    {
        
$project_dir dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR;

        
$this->databases_yml $project_dir.'config'.DIRECTORY_SEPARATOR.'___app_name____databases.yml';

        
$this->env trim(file_get_contents(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'env'));

        
$this->instance_name 'default_master';
    }


    public function 
safeChange()
    {
    }

    public function 
safeUp()
    {
    }

    public function 
safeDown()
    {
    }

    public function 
change()
    {
    }

    public function 
up()
    {
    }

    public function 
down()
    {
    }

}

クラス名は、<{app key}>_<{マイグレーション名}> というパターンです。

up() メソッドが、実際のデータベースマイグレーションを実装するコードを含むべきメソッドです。 そして down() メソッドは、up() で実行されたことを破棄するコードを含むことが出来ます。

警告: 場合によっては、down() を実装することが不可能なことがあります。 例えば、up() の中でテーブルの行を削除した場合、down() の中で行を復元することは出来ません。 このような、マイグレーションのことを、不可逆マイグレーションと呼びます。

change()メソッドは、不可逆ではないマイグレーションを記述します。 そうすることにより、up()とdown()を自動的に判断します。

不可逆なマイグレーションを記述した場合はエラーを返します。

トランザクションを使うマイグレーション

複雑な DB マイグレーションを実行するとき、通常は、データベースが一貫性と整合性を維持できるように、個別のマイグレーションが全体として成功または失敗するように配慮する必要があります。

この目的を達成するために、DB のトランザクション機能を利用することが出来ます。

up() メソッドの代りに safeUp() メソッドを実装し、down() メソッドの代りに safeDown() 、change()メソッドの代わりに、safeChange()メソッドを実装する事により、トランザクションを利用した、マイグレーションを利用できます。

警告: すべての RDBMS がトランザクションをサポートしている訳ではありません。 また、DB クエリの中には、トランザクションの中に入れることが出来ないものもあります。 その場合には、代りに up() または down() を実装しなければなりません。 また、MySQL の場合、暗黙のコミット を引き起こすSQLもあります。 暗黙コミットが行われた場合は、トランザクションのネストが壊れることがあります。

マイグレーションを適用する

利用できるすべての新しいマイグレーションを適用する (すなわち、ローカルのデータベースを最新状態に更新する) ためには、以下のコマンドを実行します。

envi db-migrate <{app key}> (env:<{環境キー}>)

コマンドを実行すると、すべての新しいマイグレーションファイル名のタイムスタンプの順に、一つずつ、すべての新しいマイグレーションクラスの up()、change() メソッドが実行されます。

env:<{環境キー}> 環境キーは、DBのエクステンション設定の環境キーを指定できます。

通常、セキュリティの観点から、Webアプリケーションからアクセスするユーザに、構造を変更する権限は与えません。 その場合は、DBの設定に、マイグレーション用のユーザーを追加する必要があります。

時として、新しいマイグレーションのうちの一つないし数個だけを適用したい場合があります。

その場合は、次のコマンドを使うことが出来ます。

envi db-up <{app key}> <実行件数> (env:<{環境キー}>)

このコマンドは、新しいマイグレーションを<実行件数>で指定した個数分だけ適用します。

マイグレーションを戻す

適用された最後のマイグレーションを、戻すためには、以下のコマンドを実行します。

envi db-rollback <{app key}> (env:<{環境キー}>)

envi db-rollbackは最後のマイグレーションのdown()メソッドや、自動で定義される、change()のロールバックを実行します。

前に説明したように、不可逆なマイグレーションも存在します。

その場合、構造は元に戻りますが、登録されているデータは戻りませんので注意して下さい。

また、最後のマイグレーションだけでは無く、複数個のマイグレーションをまとめて戻したい場合は、以下のコマンドを実行します。

envi db-down <{app key}> <実行件数> (env:<{環境キー}>)

このコマンドは、envi db-rollbackを<実行件数>で指定した個数分だけ適用します。

マイグレーション情報を表示する

マイグレーションを適用したり破棄したりする他に、マイグレーションツールはマイグレーションの履歴、および、まだ適用されていない新しいマイグレーションを表示することも出来ます。

envi db-history <{app key}> <limit>
envi db-new <{app key}> <limit>
envi db-abort_if_pending_migrations <app_key>

オプションの limit パラメータは何個のマイグレーションを表示するかを指定するものです。

最初のコマンドは適用済みのマイグレーションを表示し、第二のコマンドは適用が済んでいないマイグレーションを表示します。 第三のコマンドは、適用が済んでいないすべてのマイグレーションを表示します。

マイグレーション履歴を修正する

時として、実際には関係のあるマイグレーションを適用または破棄することなく、マイグレーション履歴を特定のマイグレーションバージョンに修正したい場合があります。 このことは新しいマイグレーションを開発するときにしばしば起ります。 次のコマンドを使ってこの目的を達することが出来ます。

envi db-cursor <{app key}> up
envi db-cursor <{app key}> down

最初のコマンドはマイグレーションのバージョンを一つ上げ、第二のコマンドはマイグレーションのバージョンを一つ下げます。

マイグレーションのテスト

マイグレーションファイルを作成している場合、意図したものになっているか知りたい場合があります。

また、環境によっては、Enviによるマイグレーションを行うことができない場合があります。

そういった場合に、実行されるSQLを表示する事ができます。

例えば以下のようにします。

envi db-migrate <app_key> --dry_run (env:<環境キー>)  
envi db-rollback <app_key> --dry_run (env:<環境キー>)  
envi db-up <app_key> <count> --dry_run (env:<環境キー>)    
envi db-down <app_key> <count> --dry_run (env:<環境キー>)    

それぞれのコマンドに--dry_runオプションを付けて実行することで、versionが変わることなく、実行予定のSQLが表示されます。