Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

「優しいIT」という理念の基、ITコンサルタントをしている亀井亮介と申します!
現在、仕事では要求分析・要件定義を中心に上流工程をしていますが、プログラムも書きます!
今回は、FuelPHPのscaffoldを利用してコードを自動生成します。
開発中にデータベースの構成が変更されて、今まで動いていた機能が動かず…いろいろ試しても開発メンバー間で、テーブルの整合性が取れていないために、余計な時間を費やした…
そんな経験はありませんか?
FuelPHPではデータベースのマイグレーションがソースファイルで管理できます(Ruby on Railsからの移植でしょう)!

●今回の目的

FuelPHPでデータベースマイグレーションを実践(今回、Dockerは関係ありません。)
CREATE文や外部キーをプログラムで制御し、開発時によくある「いつ間にかデータベースの構造が変わってエラー多発」している状態から短時間で、開発環境間の同期をとります。

●ポイント

データベース構築をやり直す場合、すべてのテーブルを手動で削除する必要あり
理由は、外部キーの参照制約により削除ができない(強制削除もできない)ため

●ホスト側環境

OS OS X El Capitan
Docker 1.9.1

●開発環境

PHP Version 5.6.18
FuelPHP Version 1.7.3
MySQL 5.7.11

●データベースマイグレーション基本編

動画解説クリック→

1. scaffoldを使いマイグレーションファイルを自動化

FuelPHPのscaffoldを使い、データベースのテーブルごとの一覧・詳細・登録・更新画面を自動生成します。
この時に、マイグレーションファイルも自動生成されます。

1-1. scaffoldを実行

scaffoldを実行
$ oil g scaffold -f firstcategories secondcategory_id:int:unsigned first_category_name:varchar[255] deleted_at:int:null
Creating migration: /Users/user/Documents/workspace/queswer/fuel/app/migrations/009_create_firstcategories.php
Creating model: /Users/user/Documents/workspace/queswer/fuel/app/classes/model/firstcategory.php
Creating controller: /Users/user/Documents/workspace/queswer/fuel/app/classes/controller/firstcategories.php
Creating view: /Users/user/Documents/workspace/queswer/fuel/app/views/firstcategories/index.php
Creating view: /Users/user/Documents/workspace/queswer/fuel/app/views/firstcategories/view.php
Creating view: /Users/user/Documents/workspace/queswer/fuel/app/views/firstcategories/create.php
Creating view: /Users/user/Documents/workspace/queswer/fuel/app/views/firstcategories/edit.php
Creating view: /Users/user/Documents/workspace/queswer/fuel/app/views/firstcategories/_form.php

コマンドが成功すると、「マイグレーション」「モデル」「コントローラー」「ビュー」のファイルが自動生成されます。

1-2. マイグレーションファイル

下記のようにup()メソッドで”create_table”が呼び出され、down()メソッドで”drop_table"が呼び出されます。

/Users/user/Documents/workspace/queswer/fuel/app/migrations/009_create_firstcategories.php
<?php

namespace Fuel\Migrations;

class Create_firstcategories
{
public function up()
    {
        \DBUtil::create_table('firstcategories', array(
            'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true, 'unsigned' => true),
            'secondcategory_id' => array('constraint' => 11, 'type' => 'int', 'unsigned' => true),
            'first_category_name' => array('constraint' => 255, 'type' => 'varchar'),
            'deleted_at' => array('constraint' => 11, 'type' => 'int', 'null' => true),
            'created_at' => array('constraint' => 11, 'type' => 'int', 'null' => true),
            'updated_at' => array('constraint' => 11, 'type' => 'int', 'null' => true),

        ), array('id'));
    }

    public function down()
    {
        \DBUtil::drop_table('firstcategories');
    }
}

2. $ oil refine migrate を実行

マイグレーションを実行すると、データベースのテーブルが生成されます。

マイグレーション実行
$ oil refine migrate
009_create_firstcategories

3. 一つ前のマイグレーションを削除

もし、マイグレーションを取り消したい場合は、downメソッドを呼びます。

一つ前のマイグレーションを削除
$ oil refine migrate:down
- 009_create_firstcategories

注意:データベースのテーブルは順番に1つずつ削除されます。2つ以上削除したい場合は、オプションをつけます。

4. $ oil refine migrate のオプション

よく使うオプション(コマンドとセット)は下記の通りです。

マイグレーションを実行
$ oil refine migrate

特にオプションを指定しないと”run”オプションが自動的に指定されます。

マイグレーションを取り消し(1つテーブルだけ)
$ oil refine migrate:down

マイグレーションのバージョンを1つ戻し、取り消します。

マイグレーションを始めに戻す(初期化)
$ oil refine migrate:down -v=0

バージョンを0にするという意味です。

マイグレーションで実行されたテーブルのレコードを削除
$ oil refine migrate:current

5. 外部参照を追加

マイグレーション時に、外部参照も含めます。
マイグレーションファイルのup()メソッドに、”add_foreign_key”メソッドを追加します。

/Users/user/Documents/workspace/queswer/fuel/app/migrations/009_create_firstcategories.php
/* 略 */
\DBUtil::add_foreign_key('firstcategories', [
    'constraint' => 'index_firstcategories_to_secondcategories',
    'key' => 'secondcategory_id',
    'reference' => [
        'table' => 'secondcategories',
        'column' => 'id',
    ],
    'on_update' => 'CASCADE',
    'on_delete' => 'CASCADE'
]);
/* 略 */

5-1. テーブル名

add_foreign_keyの第1引数でテーブル名を指定します。別テーブルを指定することも可能です。

5-2. constraint

constraintでキーの名前を指定します。任意ですが、どのテーブルからどのテーブルを見に行くか、わかるように記載しましょう。
first categoriesからsecond categoriesを参照
index_firstcategories_to_secondcategories

5-3. key

参照元のキー
例:second_category_id

5-4. reference

参照先のテーブルと関連づけるキー(主に主キー)
'reference' => [
        'table' => 'secondcategories',
        'column' => 'id',
    ],

5-5. on_update

参照先のデータが更新された時の関連動作
例:CASCADE
参照先のキーが変わると、参照元のキーも同時に変わります。

5-6. on_delete

参照先のデータが削除された時の関連動作
例:CASCADE
参照先のキーが削除されると、参照元のキーも同時に削除されます。

6. 外部参照がある場合のマイグレーションのやり直し

外部参照があるときに、マイグレーションをやり直そうとして

外部参照があるときに、マイグレーションをやり直し…エラー
$ oil refine migrate:down -v=0

としても、エラーが出て削除できません。原因は参照制約です(当たり前か 笑)。
調べてみたのですが、マイグレーションファイルのdownメソッドから強制削除できないようです(できる方法があれば誰か教えてください!)
そこで、あまりいい方法ではないと思いますが、次の手順で初期化します。

6-1. 必要なデータをバックアップ

6-2. テーブルをphpMyAdminやSequel Proなどのツールで削除

6-3. $ oil refine migrate:current を実行

6-4. データをリストア

※もっといい方法が見つかれば、この項目は更新します。

おすすめ本

リーダブルコード
レガシーコード改善ガイド
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化 Kindle版

サイトマップ(未投稿あり)

理念・価値・ビジョン・使命

テスト駆動開発を重点においた規則

コーディング規則「優しいコードを書こう」(FuelPHP)
命名規則「3ヶ月後の自分自身に優しく、チームに優しく、まだ見ぬメンバーに優しく」

Docker+PythonでWebアプリケーション開発

Docker上のCentOSにPython3と、関連ライブラリpip, virtualenvとフレームワークDjango, bottle, Flaskのインストール!これらをまとめたDockerfile付き!

開発しやすい環境構築(Docker+PHP)

Dockerを利用しApacheにPHP環境 + Eclipseを連携
Dockerを利用したFuelPHP開発環境構築
Docker利用したFuelPHP開発環境の初期設定とscaffoldを利用してCRUDスケルトン作成
FuelPHPのデータベースマイグレーション

Raspberry Pi 3 (ラズパイ)とpythonで遊ぼう

Raspberry Pi 3インストール→無線LAN→日本語入出力→Macから操作
Raspberry Pi 3でプログラミングをする Node-REDと普通にプログラミング
Raspberry Pi 3でpythonを使いLEDを光らせる(Hello World)
Raspberry Pi 3でスイッチの状態を検出する
Raspberry Pi 3でpythonを使いサーボモータを動かす

RyosukeKamei
「優しいIT」という理念の基、ITコンサルタントをしている亀井亮介と申します! 現在、仕事では要求分析から要件定義を中心に上流工程をしていますが、プログラムも書きます!2016年現在、ベンダーマネジメントが主な業務です! 「資格試験勉強をすればするほど、社会貢献ができる?」ウェブサイトを運営しており、並行してシステム構築中 http://korejoap.info/ 子供が3人いまーす
http://sr2s.org/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away