#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