このエントリーをはてなブックマークに追加

更新日: 2016年2月25日

実行時間: 0.0513

CI_Migration

 「CI_Migration」ライブラリクラスは、データベースマイグレーションをサポートする機能を提供します。

 データベースマイグレーションとは、データベースのテーブル構成の変更・更新などをバージョン管理のもと 半自動的にアップデート・ロールバックを行うものです。

 Webアプリケーションの開発では、通常、仕様変更や機能追加などのバージョンアップにより、 利用しているデータベースの構成を変更する必要が出てきます。
 そんな時に「CI_Migration」ライブラリクラスの機能を利用すると便利です。

 もし、Webアプリケーションのバージョンアップを行った後に不具合が見つかり、ロールバックを行う場合でも 「CI_Migration」ライブライクラスの機能によって、簡単にデータベースのロールバックも行うことが
可能です。

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

 データベースマイグレーションを行うには、以下の事前準備が必要になります。

    • データベース接続設定

     当然のことながらデータベース接続設定が行われている必要があります。
     データベースの接続設定は「application/config/database.php」設定ファイルで設定します。

    • マイグレーションクラスの作成

     データベースの構成を変更・更新するクラスをバージョン毎に作成します。

    • コントローラクラスの作成

     CI_Migrationライブラリクラスをロードして、データベースマイグレーションを実行する コントローラクラスを作成します。ここでロードされたCI_Migrationクラスのインスタンスメソッドによって 適切なバージョンのマイグレーションファイルが選定され実行されます。

    • CI_Migrationクラスの設定

     CI_Migrationをロードする際に、データベースマイグレーションに必要な設定情報を 「application/config/migration.php」設定ファイルで定義します。


マイグレーションクラスの作成

 マイグレーションクラスは、データベースの構成の変更が必要になった際に作成します。

 マイグレーションクラスファイルの配置

 マイグレーションクラスファイルの設置場所は、デフォルトで「application/migrations/」ディレクトリで、
ファイル名は、「3桁の数字」に続けて「_(アンダスコア)」+「文字列」+「.php」となります。

  • application/migrations/
  • 001_initial.php
    002_add_new_table.php
    003_change_column.php

 3桁の数字は、マイグレーションバージョン番号となり、「1」から「999」まで作成することができます。
 また、ファイル名が異なっても同番号のファイルを複数作成するとエラーとなります。
 「001_hogehoge.php」、「001_foobar.php」とするとエラーとなります。

 アンダスコアの後の文字列は、特にマイグレーション処理に影響することは無く、データベース構成の
変更内容が推測できるような文字列を指定することができます。

 しかし、数値以降の文字列部分が同じものは作れません。
 「001_hogehoge.php」、「002_hogehoge.php」とするとエラーとなります。


 マイグレーションクラスのクラス名

 クラス名は「Migration_」に、マイグレーションクラスファイルの「文字列」の部分の先頭を大文字にした 文字列を付けたものになります。  クラス名には、マイグレーションバージョン番号は含まれません。

  • 001_initial.php
  • Migration_Initial
  • 002_add_new_table.php
  • Migration_Add_new_table
  • 003_change_column.php
  • Migration_Change_column

 マイグレーションクラスの作成

 マイグレーションクラスは、「CI_Migration」ライブラリクラスを継承する必要があります。
 また、定義する必要のあるメソッドは「up()」と「down()」メソッドの2つです。

 「up()」メソッドには、データベース構成の変更・更新処理を定義します。また、「down()」メソッドには 「up()」メソッドに対応するロールバック処理を定義します。
 例えば、カラム追加に対し、ロールバックとしてカラム削除の処理を定義します。
(実際には、カラムの削除を行う前にデータのバックアップなどの処理が必要になるはずです。)

    <?php

    class Migration_Initial extends CI_Migration {

        public function __construct()
        {
            parent::__construct();
        }

        public function up()
        {
            /*
            アップデート処理
            */

        }

        public function down()
        {
            /*
            ロールバック処理
            */

        }

    }

 マイグレーションクラスでは、コントローラクラスなどで利用可能なCodeIgniterコアクラスのインスタンスを プロパティ変数から利用することが可能です。

        public function up()
        {
            $this->config->load('my_config');
            $this->config->item('my_item');
            $this->load->helper('array');
            $this->load->model('my_model');
        }

コントローラクラスの作成

 コントローラクラスは通常通り「application/controllers/」ディレクトリに、 CodeIgniterのコントローラルールに準拠しているかたちで作成します。

 クラス名やメソッド名は、CodeIgniterのルールに則っていれば任意に命名できます。

    <?php

    class Shop_db_migration extends CI_Controller {

        public function __construct()
        {
            parent::__construct();
        }

        public function migrate()
        {
            if ( ! $this->input->is_cli_request() ) {
                log_message('error', 'Request from HTTP is not allowed.');
                return FALSE;
            }

            $this->load->library('migration');

            if ( $this->migration->current() ) {
                log_message('error', 'Migration Success.');
            } else {
                log_message('error', $this->migration->error_string());
            }
        }
    }

 データベースマイグレーションは、アプリケーションのデプロイ時や、メンテナンス時に行うはずです。  HTTPリクエストから実行されてしまうとセキュリティ的にも推奨できません。
 従って、コマンドラインからの実行かどうか、「CI_Input」クラスの 「is_cli_request()」メソッドを利用して判定すると良いでしょう。


対象データベースの指定

 デフォルトでは、マイグレーション対象のデータベースは「application/config/database.php」の
「 [default] 」グループになります。

 もし、「 [default] 」以外のデータベースがマイグレーション対象である場合は、「CI_Migration」クラスを ロードする前に、データベースを指定してデータベースのロードを行う必要があります。

    • application/config/database.php
    $db['master']['hostname'] = 'localhost';
    $db['master']['username'] = 'username';
    $db['master']['password'] = 'password';
    $db['master']['database'] = 'shop_tbl';
           :
    • application/controller/shop_db_migration.php
        public function migrate()
        {
            $this->load->database('master');
            $this->load->library('migration');

            if ( $this->migration->current() ) {
                log_message('error', 'Migration Success.');
            } else {
                log_message('error', $this->migration->error_string());
            }
        }

エラーメッセージ

 エラーメッセージは「 error_string() 」メソッドで取得できます。

    $err_msg = $this->migration->error_string();

 エラーメッセージの多言語化にも対応しています。
 デフォルトの言語ファイルは「 system/language/english/migration.php 」です。他の言語で利用する場合は、 「application/language/[言語]/」ディレクトリにコピーして編集し、言語を設定します。

    $ cp system/language/english/migration.php application/language/japanese/
    $this->config->set_item('language', 'japanese');

    if ( ! $this->migration->current() ) {
        echo $this->migration->error_string();
    }

CI_Migrationクラスの設定

 「CI_Migration」ライブラリクラスの設定は、「application/config/migration.php」設定ファイルで
定義するか、CI_Migration ライブラリクラスをロードする際に、「CI_Loader」クラスの「library()」メソッドの 第二引数に連想配列として設定情報を指定します。

  • application/config/migration.php
項目 デフォルト 説明
migration_enabled FALSE TRUEが設定されていない限り、マイグレーション処理は行われません。
migration_path APPPATH.'migrations/' マイグレーションクラスファイルが設置してあるディレクトリパス
migration_version 0 マイグレーション処理を行う「マイグレーションバージョン番号」
(先頭番号に0を付ける必要はありません)

 「migration_version」は、現在のマイグレーション番号ではなくターゲットのマイグレーション番号です。
 例えば、現在のバージョン番号が「2」で「migration_version」を「5」にして実行した場合、
「003_***.php」「004_***.php」「005_***.php」の マイグレーションクラスの「up()」メソッドが順番に処理
されます。

    <?php

    $config['migration_enabled'] = TRUE;
    $config['migration_path'] = '';
    $config['migration_version'] = 5;

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

 設定ファイルでターゲットバージョン指定

 「application/config/migration.php」設定ファイルの「migration_version」設定値の バージョン番号をターゲットバージョンとしてマイグレーションを行います。

  • application/config/migration.php
  • <?php

    $config['migration_enabled'] = TRUE;
    $config['migration_path'] = '';
    $config['migration_version'] = 5;
  • application/controllers/shop_db_migration.php
  • public function conf_ver()
    {
        $this->load->library('migration');

        $this->migration->current();
    }
    $ php ./index.php shop_db_migration conf_ver

 実行時にターゲットバージョン指定

 「version()」メソッドに、直接バージョン番号を指定してマイグレーションを行います。

  • application/controllers/shop_db_migration.php
  • public function migrate($version=0)
    {
        $config['migration_enabled'] = TRUE;

        $this->load->library('migration', $config);

        $this->migration->version($version);
    }
    $ php ./index.php shop_db_migration migrate 5

 マイグレーションクラスファイル名から最新ターゲットバージョン番号指定

 「application/migrations/」ディレクトリ内のマイグレーションクラスファイル名のバージョン番号から 最新(一番大きい数字)のものを取得し、そのバージョンをターゲットバージョンとしてマイグレーションを行います。

  • application/migrations/
  • 001_initial.php
    002_add_new_table.php
    003_change_column.php
  • application/controllers/shop_db_migration.php
  • public function latest()
    {
        $this->load->library('migration');

        $this->migration->latest();
    }
    $ php ./index.php shop_db_migration latest

ロールバック

  • application/controllers/shop_db_migration.php
  • public function rollback($version=0)
    {
        $config['migration_enabled'] = TRUE;

        $this->load->library('migration', $config);

        $this->migration->version($version);
    }
    $ php ./index.php shop_db_migration rollback 2