今更FuelPHP感はあるのだが、
postgresql利用時のFuelPHPのmigration導入について、注意点をまとめた。
でも、結論は納得がいっていない。
0. 前提
下記の環境で行ったものです。
PHP: 5.5.7
FuelPHP: 1.7
Postgresql: 9.4
1. テーブル文字コードの問題
事象
公式サイトのサンプルの通りはじめにapp/migrations/001_example.php
を作り、migrationを実行した。
app/migrations/001_example.php
の作成
<?php
namespace Fuel\Migrations;
class Example
{
function up()
{
\DBUtil::create_table('posts', array(
'id' => array('type' => 'int', 'constraint' => 5),
'title' => array('type' => 'varchar', 'constraint' => 100),
'body' => array('type' => 'text'),
), array('id'));
}
function down()
{
\DBUtil::drop_table('posts');
}
}
マイグレーション実行すると以下のエラーに襲われた。
$ php oil refine migrate
Uncaught exception Fuel\Core\Database_Exception: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "DEFAULT"
LINE 5: )DEFAULT CHARACTER SET utf8;
^ with query: "CREATE TABLE IF NOT EXISTS "migration" (
"type" varchar(25) NOT NULL,
"name" varchar(50) NOT NULL,
"migration" varchar(100) DEFAULT '' NOT NULL
)DEFAULT CHARACTER SET utf8;"
理由
しょっぱなから躓くわけだが…
初めてマイグレーションを実行する際にはマイグレーション管理用のテーブルを作る。
そのテーブルを作るSQLが下記の通り発行されている。
CREATE TABLE IF NOT EXISTS "migration" (
"type" varchar(25) NOT NULL,
"name" varchar(50) NOT NULL,
"migration" varchar(100) DEFAULT '' NOT NULL
)DEFAULT CHARACTER SET utf8;
理由は単純で、postgresqlのcreate tableでは次のdefault構文は利用できないから。
create table xxxx ( ) default character set xxx;
なぜ、利用できない構文のSQLが発行されたのか?
それは単にFuelPHPの問題です。次期バージョンでは解決されることを祈る。
解決方法
解決方法は下記の記事がわかりやすかった。 qiita.com
簡単に言うとdbのコンフィグで、charsetをnullにするとDEFAULT CHARACTER SET xxx
部分が発行されない。
'charset' => NULL,
2. PRIMARY KEYの問題
事象
1.の文字コードの問題は解決して、さあもう一度マイグレーションを!と思って実行するもさらなるエラーに阻まれる。
$ php oil refine migrate
Uncaught exception Fuel\Core\Database_Exception: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "("
LINE 2: "id" int(5) NOT NULL,
^ with query: "CREATE TABLE IF NOT EXISTS "users" (
"id" int(5) NOT NULL,
"name" text NOT NULL,
PRIMARY KEY "id" ("id")
);"
理由は1のときと一緒。
postgresqlでは以下の構文は使えないのだ…
PRIMARY KEY "id" ("id")
3. 結局
つまるところFuelPHP(すくなくとも1.7までは)では、postgresqlでマイグレーションを行う環境がちゃんと整っていないということ。
しかたないので、マイグレーションのSQLは生SQLを書くことにしました。
PRIMARY KEYを後から別途で付与するとか考えたけど、
ほかにも罠がありそうだったので、安全な生SQLを採用しました。
バージョン1.8では直っている?とのことだが、まだdevelopmentだったのでこれも見送り。