Синтаксическая ошибка миграции после пользовательского типа Doctrine в Symfony 4

#mysql #symfony #doctrine

#mysql #symfony #doctrine

Вопрос:

Когда я пытаюсь создать пользовательский тип Doctrine, как в коде ниже:

config/packages/doctrine.yaml

 parameters:
    # Adds a fallback DATABASE_URL if the env var is not set.
    # This allows you to run cache:warmup even if your
    # environment variables are not available yet.
    # You should not need to change this value.
    env(DATABASE_URL): ''

doctrine:
    dbal:
        # configure these for your database server
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci

        url: '%env(resolve:DATABASE_URL)%'
        types:
            pickupPointDetails: AppUtilsTypesPickupPointDetailsType
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'AppEntity'
                alias: App

  

PickupPointDetailsType:

 <?php

namespace AppUtilsTypes;

use DoctrineDBALTypesType;
use DoctrineDBALPlatformsAbstractPlatform;
use AppUtilsOrderPickupPointDetails;

/**
 * Class PickupPointDetailsType
 */
class PickupPointDetailsType extends Type
{
    const PICKUP_POINT_DETAILS = 'pickupPointDetails';

    /**
     * @return string
     */
    public function getName()
    {
        return self::PICKUP_POINT_DETAILS;
    }

    /**
     * @param array            $fieldDeclaration
     * @param AbstractPlatform $platform
     *
     * @return string
     */
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return 'PICKUP_POINT_DETAILS';
    }

    /**
     * @param mixed            $value
     * @param AbstractPlatform $platform
     *
     * @return PickupPointDetails
     */
    public function convertToPHPValue($value, AbstractPlatform $platform): PickupPointDetails
    {
        list($name, $city, $informations) = sscanf($value, 'PICKUP_POINT_DETAILS(%s, %s, %s)');

        return new PickupPointDetails($name, $city, $informations);
    }

    /**
     * @param mixed            $value
     * @param AbstractPlatform $platform
     *
     * @return string
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        $value = sprintf('PICKUP_POINT_DETAILS(%s, %s, %s)', $value->getName(), $value->getCity(), $value->getInformations());

        return $value;
    }

    /**
     * @return bool
     */
    public function canRequireSQLConversion()
    {
        return true;
    }

//    /**
//     * {@inheritdoc}
//     */
//    public function requiresSQLCommentHint(AbstractPlatform $platform)
//    {
//        return true;
//    }
//
//    /**
//     * @param string           $sqlExpr
//     * @param AbstractPlatform $platform
//     *
//     * @return string
//     */
//    public function convertToPHPValueSQL($sqlExpr, $platform)
//    {
//        return sprintf('AsText(%s)', $sqlExpr);
//    }
//
//    /**
//     * @param string           $sqlExpr
//     * @param AbstractPlatform $platform
//     *
//     * @return string
//     */
//    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
//    {
//        return sprintf('PointFromText(%s)', $sqlExpr);
//    }
}
  

На следующем шаге я генерирую миграции с помощью DoctrineMigrationsBundle, и это сгенерированный код:

 /**
 * Auto-generated Migration: Please modify to your needs!
 */
final class Version20190329095621 extends AbstractMigration
{
    public function getDescription() : string
    {
        return '';
    }

    public function up(Schema $schema) : void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on 'mysql'.');

        $this->addSql('ALTER TABLE orders ADD pickup_point_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', ADD pickup_point_back_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', DROP pickup_point_data, DROP pickup_point_back_data');
    }

    public function down(Schema $schema) : void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on 'mysql'.');

        $this->addSql('ALTER TABLE orders ADD pickup_point_data VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, ADD pickup_point_back_data VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, DROP pickup_point_details, DROP pickup_point_back_details');
    }
}
  

И после выполнения миграции у меня синтаксическая ошибка в консоли:

 Migrating up to 20190329095621 from 20190329094245

     migrating 20190329095621

     -> ALTER TABLE orders ADD pickup_point_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', ADD pickup_point_back_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', DROP pickup_point_data, DROP pickup_point_back_data
Migration 20190329095621 failed during Execution. Error An exception occurred while executing 'ALTER TABLE orders ADD pickup_point_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', ADD pickup_point_back_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', DROP pickup_point_data, DROP pickup_point_back_data':

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Type:pickupPointDetails)', ADD pickup' at line 1

In AbstractMySQLDriver.php line 79:

  An exception occurred while executing 'ALTER TABLE orders ADD pickup_point_details PICKUP_POINT_DETAILS NOT NULL C
  OMMENT '(DC2Type:pickupPointDetails)', ADD pickup_point_back_details PICKUP_POINT_DETAILS NOT NULL COMMENT '(DC2Ty
  pe:pickupPointDetails)', DROP pickup_point_data, DROP pickup_point_back_data':

  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual tha
  t corresponds to your MySQL server version for the right syntax to use near 'PICKUP_POINT_DETAILS NOT NULL COMMENT
   '(DC2Type:pickupPointDetails)', ADD pickup' at line 1


In PDOConnection.php line 90:

  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual tha
  t corresponds to your MySQL server version for the right syntax to use near 'PICKUP_POINT_DETAILS NOT NULL COMMENT
   '(DC2Type:pickupPointDetails)', ADD pickup' at line 1


In PDOConnection.php line 88:

  SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual tha
  t corresponds to your MySQL server version for the right syntax to use near 'PICKUP_POINT_DETAILS NOT NULL COMMENT
   '(DC2Type:pickupPointDetails)', ADD pickup' at line 1
  

У кого-нибудь есть идеи, что я сделал неправильно?

Symfony 4

Комментарии:

1. ваш getSQLDeclaration неверен, он должен возвращать определение столбца sql (плюс прочее), вы возвращаете что-то …. странное, например, название поля с заглавной буквы. это должно быть «VARCHAR(100)» или «INT» или что-то еще.

2. @Jakumi Я создал свой код с помощью этого руководства doctrine-project.org/projects/doctrine-dbal/en/latest/reference /… . Я исправляю свой код с вашей информацией, и это работает! Спасибо

3. перед этим в руководстве есть важная строка CREATE DOMAIN MyMoney AS DECIMAL(18,3); , которая преобразует «MyMoney» в фактический тип. Значит, это работает в руководстве… однако это зависит от postgresql