Edited at
CakePHPDay 14

CakePHP Migrations の limit オプションについて

More than 1 year has passed since last update.

これは CakePHP Advent Calendar 2017 の第14日目の記事です。

CakePHP の Slackチャンネル話題に上がっていたので前倒しで公開します。


三行


  • CakePHP の Migrations は、XXXXINT 系のカラムが苦手な模様。

  • とりあえず対応は可能。

  • 多分、根本的な解決には CakePHP 本体の対応が必要:sweat:


発端

CREATE TABLE `users` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`gender` tinyint(4) NOT NULL DEFAULT '0',
`created` datetime,
`modified` datetime,
PRIMARY KEY (`id`)
);

上記 schema で bake migration_snapshot したマイグレーションファイルを実行すると、以下の例外が投げられてマイグレーションが実行できない。


Exception: An invalid column type "tinyinteger" was specified for column "gender". in [/path/to/vendor/robmorgan/phinx/src/Phinx/Db/Table.php, line 351]



とりあえずの対応方法

該当のカラムの type を変更し、limit に Phinx のオプションを設定する。

http://docs.phinx.org/en/latest/migrations.html#limit-option-and-mysql

-            ->addColumn('gender', 'tinyinteger', [

+ ->addColumn('gender', 'integer', [
'default' => '0',
- 'limit' => 4,
+ 'limit' => Phinx\Db\Adapter\MysqlAdapter::INT_TINY,
'null' => false,
])

または

 <?php

use Migrations\AbstractMigration;
+use Phinx\Db\Adapter\MysqlAdapter;

- ->addColumn('gender', 'tinyinteger', [
+ ->addColumn('gender', 'integer', [
'default' => '0',
- 'limit' => 4,
+ 'limit' => MysqlAdapter::INT_TINY,
'null' => false,
])


他の type は?

他の type についても状況を確認。


  • ○: マイグレーションファイルを実行でき、type の変更もない。

  • △: マイグレーションファイルを実行できるが、type が変更される。

  • error: マイグレーションファイルを実行できない。

元の type
結果
作成された type

TINYBLOB

BINARY(255)

BLOB

BINARY(255)

MEDIUMBLOB
error

LONGBLOB
error

TINYTEXT

TINYTEXT

TEXT

TEXT

MEDIUMTEXT

MEDIUMTEXT

LONGTEXT

LONGTEXT

TINYINT
error

SMALLINT
error

MEDIUMINT

INT(9)

INT

INT

BIGINT

BIGINT

blob は binary として扱われる。MEDIUMBLOB, LOGNBLOB の場合、以下のエラーになる。


SQLSTATE[42000]: Syntax error or access violation: 1074 Column length too big for column 'blob_long' (max = 255); use BLOB or TEXT instead


対応

-            ->addColumn('blob_long', 'binary', [

+ ->addColumn('blob_long', 'blob', [
'default' => null,
- 'limit' => 4294967295,
+ 'limit' => Phinx\Db\Adapter\MysqlAdapter::BLOB_LONG,
'null' => true,


PostgreSQL の場合

SAMLLINT は、Exception: An invalid column typeが投げられる。

http://docs.phinx.org/en/latest/migrations.html#limit-option-and-postgresql

-            ->addColumn('gender', 'smallinteger', [

+ ->addColumn('gender', 'integer', [
'default' => null,
- 'limit' => 5,
+ 'limit' => Phinx\Db\Adapter\PostgresAdapter::INT_SMALL,
'null' => false,

BIGINTはシンタックスエラー...


Exception: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "("

LINE 1: ...users" ("id" BIGSERIAL NOT NULL, "big_int" BIGINT (20) NOT N...


対応

             ->addColumn('big_int', 'biginteger', [

'default' => null,
- 'limit' => 20,
+ 'limit' => null,
'null' => false,
])


まとめ

多分、CakePHP 本体の対応が必要...


環境


  • CakePHP: 3.5.7

  • CakePHP Migrations: 1.7.1

  • Phinx: 0.8.1

  • PHP: 7.1.0

  • MySQL: 5.7.20

  • PostgreSQL: 10.1


明日は @keisukefunatsu さんです。