【问题标题】:Doctrine DBAL, diff command and enum typeDoctrine DBAL、diff 命令和枚举类型
【发布时间】:2021-01-22 07:48:59
【问题描述】:

我正在使用 symfony 5.1、教义捆绑包 2.1.2 和教义迁移捆绑包 2.2。我没有使用 ORM 并定义我自己的模式。要添加枚举类型,我使用以下代码:

abstract class EnumType extends Type
{
    protected string $name;

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        $values = $this->getValues();
        $maxLength = max(array_map('strlen', $values));
        $columnName = $fieldDeclaration['name'];

        $implodedValues = implode(', ', array_map(function($value) {return "'$value'";}, $values));

        if ($platform instanceof MySqlPlatform) {
            return "ENUM($implodedValues)";
        }

        if (
            $platform instanceof SQLServer2012Platform
            || $platform instanceof PostgreSQL94Platform
        ) {
            return "VARCHAR($maxLength) CHECK ({$columnName} IN ($implodedValues))";
        }

        if ($platform instanceof SqlitePlatform) {
            return "TEXT CHECK ({$columnName} IN ($implodedValues))";
        }

        throw DBALException::invalidPlatformType($platform);
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (!in_array($value, $this->getValues())) {
            throw new \InvalidArgumentException("Invalid '" . $this->name . "' value: " . (string)$value);
        }
        return $value;
    }

    public function getName()
    {
        return $this->name;
    }

    public function requiresSQLCommentHint(AbstractPlatform $platform)
    {
        return true;
    }

    abstract function getValues(): array;
}

每个枚举然后扩展这个抽象类来设置值。

创作不是问题。当我运行迁移差异命令时,我收到以下错误消息:

请求的数据库类型枚举未知,Doctrine\DBAL\Platforms\MySQL57Platform 可能不支持。

有什么想法可以创建一个包含对枚举本身的任何更改的差异吗?

【问题讨论】:

    标签: php symfony doctrine-migrations doctrine-dbal


    【解决方案1】:

    我通过创建自己的 diff 解决了这个问题,它首先添加了“枚举”类型(如果还没有的话):

    if ($connection->getDatabasePlatform() instanceof MySqlPlatform) {
        if (!Type::hasType('enum')) {
            Type::addType('enum', StringType::class);
        }
        $connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum', Types::STRING);
    }
    

    之后我尝试读取所有可用的表,并捕获未定义类型的任何异常,将其定义为字符串,然后重试:

    $schemaManager = $this->connection->getSchemaManager();
    do {
        try {
            return new Schema($schemaManager->listTables(), [], $schemaManager->createSchemaConfig());
        } catch (Exception $exception) {
            $hasErrors = true;
            $message = $exception->getMessage();
            $parts = explode('"', $message);
            // convert any removed custom type to string
            Type::addType($parts[1], StringType::class);
        }
    } while ($hasErrors);
    

    这将返回当前的数据库架构。可以使用新架构从中创建差异。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 2014-01-27
      • 2016-07-04
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多