migrations
migrations copied to clipboard
Custom doctrine types keep getting their definition generated in migrations
| Q | A |
|---|---|
| ORM | 3.2.0 |
| DBAL | 4.0.3 |
Support Question
I have recently upgrade doctrine to DBAL 4 / ORM 3, and when I run make:migration, then run doctrine:migration:migration, then run make:migration again, the exact same file is generated, with the same changes.... From what I see, the big majority of those changes are related to custom doctrine type, and I believe it is related to the fact that "Type::requiresSQLCommentHint()" has been removed from doctrine
My problem seems very similar to https://github.com/doctrine/migrations/issues/1434 that you closed, except that in my case, I'm using MySQL and I removed all comments related to DC2Type. But still, make:migration keeps generating those changes, over and over again.
Any way to fix this?
Please share a reproducer for the issue.
Also, which version of doctrine/migrations are you using ?
I am using doctrine/doctrine-migrations-bundle v3.3.1, which itself uses doctrine/migrations v3.7.4
Here's an example of custom type that keeps getting generated, but used to work perfectly before, with DC2Type comments:
<?php
namespace App\Doctrine\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Override;
class AmountType extends Type
{
public const AMOUNT = 'amount';
/**
* {@inheritDoc}
*/
#[Override]
public function convertToPHPValue($value, AbstractPlatform $platform): ?float
{
return null !== $value ? (float) $value : null;
}
/**
* {@inheritDoc}
*/
#[Override]
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$column['precision'] = max($column['precision'], 16);
$column['scale'] = max($column['scale'], 2);
$declaration = 'DECIMAL(' . $column['precision'] . ', ' . $column['scale'] . ')';
$declaration .= $column['unsigned'] ? ' UNSIGNED' : '';
return $declaration;
}
}
and another example:
<?php
namespace App\Doctrine\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\IntegerType;
use Override;
class TinyInt extends IntegerType
{
public const string TINYINT = 'tinyint';
/**
* @param array $column
* @param AbstractPlatform $platform
*
* @return string
*/
#[Override]
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$autoinc = '';
if (!empty($column['autoincrement'])) {
$autoinc = ' AUTO_INCREMENT';
}
return 'TINYINT' . (!empty($column['unsigned']) ? ' UNSIGNED' : '') . $autoinc;
}
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
{
return true;
}
public function getName(): string
{
return self::TINYINT;
}
}
so, when I run make:migration, then run doctrine:migration:migrate, then run make:migration again, every column using one of these customTypes are getting their definition generated every time
Let me know if I shall add more details / code.
Hello @geoffroyp ,
Have you found a solution? I have exactly the same problem. Thanks :)
Nope, I have downgraded my doctrine so far, waiting for a fix about it.
Judging by your message, I believe it's still not fixed... :(
May be also related to https://github.com/doctrine/dbal/issues/6743, I have working TinyInt with some workaround in that issue, this can be solved just by removing (1) part from mysql boolean definition TINYINT(1), there was also PR https://github.com/doctrine/dbal/pull/6569 but it was closed due to inactivity.
Hi,
I recently decided to spend some time digging into this issue again. It seems a few of us still encounter the migration diff problem with tinyint on MySQL when using Doctrine.
I finally found a solution that works for my case. It’s the best way but it stops the endless diffs in migrations.
What I did:
Custom type : Tinyint
use Doctrine\DBAL\Types\IntegerType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class TinyintType extends IntegerType
{
public const TINYINT = 'tinyint';
public function getName(): string
{
return self::TINYINT;
}
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$declaration = 'TINYINT' . (!empty($column['unsigned']) ? ' UNSIGNED' : '');
return !empty($column['autoincrement']) ? $declaration . ' AUTO_INCREMENT' : $declaration;
}
}
Custom type : Boolean This one only overrides the getSQLDeclaration() for boolean, but I still use Types::BOOLEAN in my entity code. Without this override, I consistently saw migrations trying to re-apply TINYINT(1) for boolean columns.
use Doctrine\DBAL\Types\BooleanType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Types;
class GABooleanType extends BooleanType
{
public function getName(): string
{
return Types::BOOLEAN;
}
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return 'TINYINT';
}
}
Doctrine config Note the importance of the mapping_types section.
doctrine:
dbal:
default_connection: default
connections:
default:
driver: 'pdo_mysql'
server_version: '8.0.41'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collation: utf8mb4_unicode_ci
url: '%doctrine-url%'
mapping_types:
tinyint: tinyint
boolean: boolean
profiling_collect_backtrace: '%kernel.debug%'
use_savepoints: true
types:
tinyint: App\Doctrine\DBAL\Types\TinyintType
boolean: App\Doctrine\DBAL\Types\GABooleanType
[...]
In my case, the project is still in development, so I was able to reset the migrations folder (delete all files and generate a fresh migration).
The goal was to start from a clean schema, removing all leftover COMMENT from previous Doctrine versions for custom types.
Obviously, in a production you can't just reset the DB schema this way. You’d need a different process.
Hope this helps others facing the same issue.