Нестандартный тип Doctrine всегда меняет таблицу
Я добавил пользовательский тип, например:
namespace My\SuperBundle\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class Money extends Type
{
const MONEY = 'money';
public function getSqlDeclaration(
array $fieldDeclaration,
AbstractPlatform $platform
) {
return 'DECIMAL(10,2)';
}
public function getName()
{
return self::MONEY;
}
}
И в моем приложении boot:
namespace My\SuperBundle;
use Doctrine\DBAL\Types\Type;
use My\SuperBundle\Types\Money;
class MyBSuperBundle extends Bundle
{
public function boot()
{
//add custom quantity and wight types
$em = $this->container->get('doctrine.orm.entity_manager');
if(!Type::hasType(Money::MONEY)) {
Type::addType(Money::MONEY, 'My\SuperBundle\Types\Money');
}
}
}
Однако каждый раз я обновляю базу данных с помощью
php app/console doctrine:schema:update --dump-sql
Я продолжаю получать следующее:
ALTER TABLE product_price CHANGE price price DECIMAL(10,2) DEFAULT NULL
Кроме того, все работает отлично. Поля в БД правильны.
Есть ли причина, по которой доктрина постоянно обновляется с теми же данными?
Ответы
Ответ 1
Вы должны переопределить метод requiresSQLCommentHint(AbstractPlatform $platform)
и вернуть true
. Таким образом, доктрина будет помнить пользовательский тип.
namespace My\SuperBundle\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class Money extends Type
{
const MONEY = 'money';
public function getSqlDeclaration(
array $fieldDeclaration,
AbstractPlatform $platform
) {
return 'DECIMAL(10,2)';
}
public function getName()
{
return self::MONEY;
}
/**
* @inheritdoc
*/
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}
Источник: Использовать комментарии столбца для дальнейшего ввода типа Doctrine
Ответ 2
Есть альтернативный способ сделать это с помощью конфигураций.
config.yml:
doctrine:
dbal:
types: { money: My\SuperBundle\Types\Money }
connections:
your_connection_name:
mapping_types: { money: money }
Источники:
Ответ 3
Вы не говорите платформе DBAL о своем типе, поэтому, очевидно, утилиты самоанализа схемы DBAL не могут ее распознать. Чтобы зарегистрировать тип, вы можете сделать следующее:
use Doctrine\DBAL\Types\Type;
use My\SuperBundle\Types\Money;
class MyBSuperBundle extends Bundle
{
public function boot()
{
/* @var $em \Doctrine\ORM\EntityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
if( ! Type::hasType(Money::MONEY)) {
Type::addType(Money::MONEY, 'My\SuperBundle\Types\Money');
$entityManager
->getConnection()
->getDatabasePlatform()
->registerDoctrineTypeMapping('decimal', Money::MONEY);
}
}
}
Это должно помешать DBAL жаловаться на различия схем.
Ответ 4
У меня была та же проблема с ZF2.
Я решил удалить дефис в моем имени пользовательского типа.
Неправильно:
'doctrine_type_mappings' => [
'custom-type' => 'custom-type'
],
Хорошо:
'doctrine_type_mappings' => [
'customtype' => 'customtype'
],
Подробнее о реализации в Zend Framework 2: https://github.com/doctrine/DoctrineORMModule/blob/master/docs/EXTRAS_ORM.md
Я надеюсь, что это может помочь кому-то.