【问题标题】:How to define the descriminator column as ENUM for Class Table Inheritance in Doctrine's?如何在 Doctrine 中将鉴别器列定义为类表继承的 ENUM?
【发布时间】:2018-06-19 17:05:30
【问题描述】:

我想实现Class Table Inheritance:

/**
 * Foo
 *
 * @ORM\Table(name="foos", ...)
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "bar" = "Bar",
 *     "buz" = "Buz"
 * })
 */
abstract class Foo
{
    ...
}

由于我运行“代码优先”的方法,所以数据库是由 Doctrine 生成的:

$ bin/console doctrine:migrations:diff
$ bin/console doctrine:migrations:migrate

鉴别器列foos.type 获取类型VARCHAR(255)。我希望它改为获得ENUM

如何定义实体类的注解以获取ENUM判别器?

【问题讨论】:

标签: mysql inheritance enums doctrine-orm class-table-inheritance


【解决方案1】:

它适用于columnDefinition="ENUM('bar', 'buz')":

/**
 * Foo
 *
 * @ORM\Table(name="foos", ...)
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string", columnDefinition="ENUM('bar', 'buz')")
 * @ORM\DiscriminatorMap({
 *     "bar" = "Bar",
 *     "buz" = "Buz"
 * })
 */
abstract class Foo
{
    ...
}

不幸的是,它会导致烦人的副作用(同样是 here):Doctrine 的迁移机制似乎无法正确处理 ENUMs。 doctrine:migrations:diff 命令创建如下迁移:

final class Version20180619205625 extends AbstractMigration
{
    public function up(Schema $schema) : void
    {
        $this->addSql('ALTER TABLE foos CHANGE type `type` ENUM(\'bar\', \'buz\')');
    }

    public function down(Schema $schema) : void
    {
        $this->addSql('ALTER TABLE tasks CHANGE `type` type VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci');
    }
}

我执行它,type 列变成了ENUM。但是 doctrine:migrations:diff 的新执行会再次创建具有相同内容的迁移...意味着,Doctrine “认为”,该列仍然是 VARCHAR

【讨论】:

    【解决方案2】:

    答案有点晚,但解决方案是注册一个自定义映射类型,该类型实际上将在数据库端使用 ENUM。最简单的:

    class YourType extends Type
    {
        public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
        {
            return 'ENUM(\'one\', \'two\')';
        }
    }
    

    在您的 Doctrine 配置中以 your_type 名称注册它并使用:

     @ORM\DiscriminatorColumn(name="type", type="your_type")
    

    默认情况下,此字段将为 NOT NULL。在 mysql 的情况下,它将使用 ENUM 中的第一个值作为默认值,就像“隐式默认值”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      相关资源
      最近更新 更多