phpmigによるマイグレーション

さすがにDBの作成はマイグレーションツールに頼りましょう、と思い立ったのでphpmigを試すことにしました。

1. インストール

まずはインストール。composer経由でインストールするためにrequire-devに追加します。

    "require-dev": {
        "davedevelopment/phpmig": "^v1.6.0",
        "vlucas/phpdotenv": "^v4.1.0"
    }

2. phpdptenvの設定

DB接続情報は環境変数として.envに持たせたかったので、phpdotenvも追加します。

.env

.gitignore.envは無視するように追加し、.envファイルを作成。

MYSQL_DBNAME=hoge_db
MYSQL_USER=hoge_user
MYSQL_PASSWORD=hoge_password
MYSQL_HOST=localhost
MYSQL_PORT=3306

.envには接続に必要な情報を記述しておきます。

3. 初期化

$ vendor/bin/phpmig init
+d .\migrations Place your migration files in here
+f .\phpmig.php Create services in here

vendor/bin/phpmigの初期化コマンドをキックします。

4. コードの編集・改造

ルートディレクトリにphpmig.phpが作成されるので、中身を改造。

<?php

use \Phpmig\Adapter;
use \Pimple\Container;

// find environment file
$dot_env = __DIR__. '/.env';
if (is_readable($dot_env)) {
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__. '/');
    $dotenv->load();
}

//$container = new ArrayObject();
$container = new Container();

// replace this with a better Phpmig\Adapter\AdapterInterface
$container['phpmig.adapter'] = new Adapter\File\Flat(__DIR__ . DIRECTORY_SEPARATOR . 'migrations/.migrations.log');

//DBの接続情報
$container['db'] = function(){
    $dbh = new PDO('mysql:dbname=' . getenv('MYSQL_DBNAME') . ';host='  . getenv('MYSQL_HOST') .  ';port=' . getenv('MYSQL_PORT') . ';charset=utf8', getenv('MYSQL_USER') , getenv('MYSQL_PASSWORD'));
    $dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
};

$container['phpmig.migrations_path'] = __DIR__ . DIRECTORY_SEPARATOR . 'migrations';

return $container;

今回はテストなので、マイグレーション情報はファイルのままで良いかな、と思いContainerの採用とDB接続情報を上述の通り.envから拾ってくる形で記述しました。

5. マイグレーションファイルの作成

$ vendor/bin/phpmig generate AddTest
+f .\migrations\20200124033140_AddTest.php

続いてテストテーブルのマイグレーションファイルを生成。

<?php

use Phpmig\Migration\Migration;

class AddTest extends Migration
{
    /**
     * Do the migration
     */
    public function up()
    {
        $sql ="
        CREATE TABLE tests(
            `id` integer(11) NOT NULL AUTO_INCREMENT,
            `name` varchar(190) NOT NULL,
            `delete_flg` boolean NOT NULL DEFAULT false,
            `created_at` datetime DEFAULT CURRENT_TIMESTAMP(),
            `updated_at` datetime DEFAULT CURRENT_TIMESTAMP(),
            PRIMARY KEY (`id`)
            );
            ";
        $container = $this -> getContainer();
        $container['db']->query($sql);
    }

    /**
     * Undo the migration
     */
    public function down()
    {
        $sql = "
        DROP TABLE tests
        ";
        $container = $this->getContainer();
        $container['db']->query($sql);
    }
}

参考記事そのままですが、マイグレーションファイルの中にSQL文を記述してみます。

6. マイグレーション

$ vendor/bin/phpmig migrate 
 == 20200124033140 AddTest migrating
 == 20200124033140 AddTest migrated 0.0270s

これでマイグレーションを実行。

マイグレーション実行でテーブルが生成された
マイグレーション実行でテーブルが生成された

すると、上述のupで記述したテーブルが生成されました。

7. ロールバック

$ vendor/bin/phpmig rollback
 == 20200124033140 AddTest reverting
 == 20200124033140 AddTest reverted 0.0272s

今度はロールバックしてみます。

ロールバックでテーブル削除
ロールバックでテーブル削除

今回はドロップなのでテーブルが削除されました。

8. ID指定ロールバック

続いてIDを指定してロールバックします。まずstatusでIDを確認。

$ vendor/bin/phpmig status

 Status   Migration ID    Migration Name
-----------------------------------------
     up  20200124035658  AddHoge
     up  20200124050245  AddFuga
   down  20200124050546  AddPiyo

確認したIDを指定してロールバック実行。

> vendor/bin/phpmig rollback -t 20200124035658
 == 20200124050245 AddFuga reverting
 == 20200124050245 AddFuga reverted 0.0334s

削除されました。


サクッと触ってみましたが、マイグレーション良いですね。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。