Doctrineに様々なデータ型のカラムをimportしてみる


動機・背景

既存のMySQLデータベースから、Doctrineを使ってEntityクラスを生成する機会がありましたが、上手くインポートできなかったり、期待とは異なるデータ型になる事があったため、調査の目的で様々なデータ型のカラムを持つテーブルをインポートしてみました。


環境


  • php 7.0.2

  • symfony 3.0.1

  • doctrine/orm 2.5.3

  • MySQL 5.5


Importしたテーブル

CREATE TABLE `test` (

`id` int(11) NOT NULL,
`test_int` int(11) DEFAULT NULL,
`test_tinyint` tinyint(4) DEFAULT NULL,
`test_tinyint_unsigned` tinyint(3) unsigned DEFAULT NULL,
`test_flg` tinyint(1) DEFAULT NULL,
`test_smallint` smallint(6) DEFAULT NULL,
`test_mediumint` mediumint(9) DEFAULT NULL,
`test_bigint` bigint(20) DEFAULT NULL,
`test_float` float DEFAULT NULL,
`test_double` double DEFAULT NULL,
`test_double43` double(4, 3) DEFAULT NULL,
`test_double_unsigned` double unsigned DEFAULT NULL,
`test_date` date DEFAULT NULL,
`test_datetime` datetime DEFAULT NULL,
`test_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
`test_time` time DEFAULT NULL,
`test_year` year(4) DEFAULT NULL,
`test_char` char(10) DEFAULT NULL,
`test_varchar` varchar(10) DEFAULT NULL,
`test_binary` binary(10) DEFAULT NULL,
`test_varbinary` varbinary(10) DEFAULT NULL,
`test_tinyblob` tinyblob,
`test_blob` blob,
`test_mediumblob` mediumblob,
`test_longblob` longblob,
`test_tinytext` tinytext,
`test_text` text,
`test_mediumtext` mediumtext,
`test_longtext` longtext,
`test_set`
set('abc', 'def', 'ghi') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8


既存のテーブルからEntityを作成する

コマンド

php bin/console doctrine:mapping:convert annotation ./src/AppBundle/Entity --from-database --filter='Test'

生成されたEntityクラス

<?php

use Doctrine\ORM\Mapping as ORM;

/**
* Test
*
* @ORM\Table(name="test")
* @ORM\Entity
*/

class Test
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/

private $id;

/**
* @var integer
*
* @ORM\Column(name="test_int", type="integer", nullable=true)
*/

private $testInt;

/**
* @var boolean
*
* @ORM\Column(name="test_tinyint", type="boolean", nullable=true)
*/

private $testTinyint;

/**
* @var boolean
*
* @ORM\Column(name="test_tinyint_unsigned", type="boolean", nullable=true)
*/

private $testTinyintUnsigned;

/**
* @var boolean
*
* @ORM\Column(name="test_flg", type="boolean", nullable=true)
*/

private $testFlg;

/**
* @var integer
*
* @ORM\Column(name="test_smallint", type="smallint", nullable=true)
*/

private $testSmallint;

/**
* @var integer
*
* @ORM\Column(name="test_mediumint", type="integer", nullable=true)
*/

private $testMediumint;

/**
* @var integer
*
* @ORM\Column(name="test_bigint", type="bigint", nullable=true)
*/

private $testBigint;

/**
* @var float
*
* @ORM\Column(name="test_float", type="float", precision=10, scale=0, nullable=true)
*/

private $testFloat;

/**
* @var float
*
* @ORM\Column(name="test_double", type="float", precision=10, scale=0, nullable=true)
*/

private $testDouble;

/**
* @var float
*
* @ORM\Column(name="test_double43", type="float", precision=4, scale=3, nullable=true)
*/

private $testDouble43;

/**
* @var float
*
* @ORM\Column(name="test_double_unsigned", type="float", precision=10, scale=0, nullable=true)
*/

private $testDoubleUnsigned;

/**
* @var \DateTime
*
* @ORM\Column(name="test_date", type="date", nullable=true)
*/

private $testDate;

/**
* @var \DateTime
*
* @ORM\Column(name="test_datetime", type="datetime", nullable=true)
*/

private $testDatetime;

/**
* @var \DateTime
*
* @ORM\Column(name="test_timestamp", type="datetime", nullable=false)
*/

private $testTimestamp = '0000-00-00 00:00:00';

/**
* @var \DateTime
*
* @ORM\Column(name="test_time", type="time", nullable=true)
*/

private $testTime;

/**
* @var \DateTime
*
* @ORM\Column(name="test_year", type="date", nullable=true)
*/

private $testYear;

/**
* @var string
*
* @ORM\Column(name="test_char", type="string", length=10, nullable=true)
*/

private $testChar;

/**
* @var string
*
* @ORM\Column(name="test_varchar", type="string", length=10, nullable=true)
*/

private $testVarchar;

/**
* @var binary
*
* @ORM\Column(name="test_binary", type="binary", nullable=true)
*/

private $testBinary;

/**
* @var binary
*
* @ORM\Column(name="test_varbinary", type="binary", nullable=true)
*/

private $testVarbinary;

/**
* @var string
*
* @ORM\Column(name="test_tinyblob", type="blob", length=255, nullable=true)
*/

private $testTinyblob;

/**
* @var string
*
* @ORM\Column(name="test_blob", type="blob", length=65535, nullable=true)
*/

private $testBlob;

/**
* @var string
*
* @ORM\Column(name="test_mediumblob", type="blob", length=16777215, nullable=true)
*/

private $testMediumblob;

/**
* @var string
*
* @ORM\Column(name="test_longblob", type="blob", nullable=true)
*/

private $testLongblob;

/**
* @var string
*
* @ORM\Column(name="test_tinytext", type="text", length=255, nullable=true)
*/

private $testTinytext;

/**
* @var string
*
* @ORM\Column(name="test_text", type="text", length=65535, nullable=true)
*/

private $testText;

/**
* @var string
*
* @ORM\Column(name="test_mediumtext", type="text", length=16777215, nullable=true)
*/

private $testMediumtext;

/**
* @var string
*
* @ORM\Column(name="test_longtext", type="text", nullable=true)
*/

private $testLongtext;

/**
* @var array
*
* @ORM\Column(name="test_set", type="simple_array", nullable=true)
*/

private $testSet;
}


分かったこと



  • tinyintのカラムはデータ長に関わらずtype="boolean"になる。


  • Date, Time, Datetime, TimestampはすべてDateTimeになる。


  • CURRENT_TIMESTAMPが設定されているカラムは、デフォルト値にString'CURRENT_TIMESTAMP'が代入される。

  • MySQLの場合、コマンドを使ってEntityを自動生成するとstrategy=IDENTITYになる。

  • 複合主キーのテーブルはstrategy=NONEになる。

  • プライマリキーがなければエラーになる。


Strategyとは何か

項目
内容

AUTO
データベースの種類に応じて、IDENTITY or SEQUENCEを自動的に選択。

SEQUENCE
自動連番。Oracle, PostgreSQL向け。

IDENTITY
自動連番。MySQL, SQLite (AUTO_INCREMENT), MSSQL(IDENTITY), PostgreSQL (SERIAL)。

NONE
上記のような設定をDoctrineが自動的にできなかった場合にNONEになる。重複は自分で何とかする必要がある。

参照

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html