CakeSchemaはENUMやInnoDBを扱えない

CakePHPには、テーブルを初期化・作成するSchema機能があります。
現在のDBからSchema設定を作成したり、
以前のSchemaとの差分を更新するSchema設定を作成したり、
database.phpのテーブル名prefixにも対応しているので、
システムのインストール・アップデートに非常に有効です。


しかし、DBの設計によっては、CakeSchemaを使えないケースがあります。(以下、MySQL)



1.ENUMを使えない
ENUM形式のカラムがあると、schema作成で以下のようなNoticeが出ます。

[cake@cake cake-install]$ ./cake/console/cake schema generate

Welcome to CakePHP v1.2.4.8284 Console
---------------------------------------------------------------
App : app
Path: /[CakeROOT]/app
---------------------------------------------------------------
Cake Schema Shell
---------------------------------------------------------------
Generating Schema...
Notice: Schema generation error: invalid column type enum('public','private') does not exist in DBO in /[CakeROOT]/cake/libs/model/schema.php on line 475
PHP Notice:  Schema generation error: invalid column type enum('public','private') does not exist in DBO in /[CakeROOT]/cake/libs/model/schema.php on line 475


作成されたschema.phpには、ENUM型のカラム情報がありません。string(varchar)などの適当な型に変換する、という処理ではなく、カラムそのものが無視されます。
当然、このschemaからテーブルを作成すると、ENUM型のカラムが存在しないテーブルが作成されます。

そしてもし、INDEXなどでENUM型カラムを参照していると、テーブルを作成しようとした時の処理がエラーになり、テーブルは作成されません。


これは、MySQL用のDBOにENUMの設定がない=対応していない ためのようです。

stringなどの適当な型で代替する、という処理は、無いようです。


DBOのソースを見る範囲、安心して使用できるのは、string(char, varchar), text, integer, float, datetime, timestamp, time, date, binary(blob), boolean(tinyint)。

LONTEXT, BIGINT程度ならTEXTやINTで解釈してくれるようです。


cake/libs/model/datasources/dbo/dbo_mysql.php

/**
 * MySQL column definition
 *
 * @var array
 */
	var $columns = array(
		'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'),
		'string' => array('name' => 'varchar', 'limit' => '255'),
		'text' => array('name' => 'text'),
		'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
		'float' => array('name' => 'float', 'formatter' => 'floatval'),
		'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
		'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
		'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
		'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
		'binary' => array('name' => 'blob'),
		'boolean' => array('name' => 'tinyint', 'limit' => '1')
	);


2.ストレートエンジンがMySAMになる
CakeSchemaでは、ストレートエンジンの設定がされません。
なので自動的に、デフォルトストレートエンジンであるMySAMになります。

このため、InnoDBや外部キー制約を用いている場合、CakeSchemaを使う事ができません・・・



あと、これは些細ですが
3. app/model以下に app_model.php があると schema作成ができない
 対応するテーブルのないmodelがあるとエラーになるので、schemaを作成する時はapp_model.phpを避難させておきましょう



便利そうな機能なのですが、私の場合テーブル定義的に使えない状態になっていて残念です。

でも、ソース的には興味深く、インストーラ作成のヒントになりそうです。


CakeSchema使用の参考サイト

CookBook
http://book.cakephp.org/ja/compare/735/Generating-and-using-Schema-files/cakephp/cakephp1x
http://book.cakephp.org/ja/view/736/Migrations-with-CakePHP-schema-shell

参考サイト
【CakePHP】お手軽便利なCakeSchema | ECWorks Blog
http://www.ryuzee.com/contents/blog/2887