はじめに
「優しい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を実行
$ 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"が呼び出されます。
<?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”オプションが自動的に指定されます。
$ oil refine migrate:down
マイグレーションのバージョンを1つ戻し、取り消します。
$ oil refine migrate:down -v=0
バージョンを0にするという意味です。
$ oil refine migrate:current
5. 外部参照を追加
マイグレーション時に、外部参照も含めます。
マイグレーションファイルのup()メソッドに、”add_foreign_key”メソッドを追加します。
/* 略 */
\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+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を使いサーボモータを動かす