Maison  >  Article  >  développement back-end  >  Ignorer les index personnalisés sur Doctrine DBAL 4

Ignorer les index personnalisés sur Doctrine DBAL 4

王林
王林original
2024-07-28 00:10:32419parcourir

Ignore custom indexes on Doctrine DBAL 4

Vous pouvez créer des index de base de données en utilisant l'attribut #[ORMIndex(fields: ['fieldName'] sur le fichier d'entité et Doctrine fera le reste pour gérer l'index pour vous, mais je le ferai ne parle pas de ça

À mesure que votre projet se développe ou nécessite des exigences spécifiques, vous devrez peut-être utiliser des types d'index personnalisés tels que GIST, GIN, BRIN, etc. (https://www.postgresql.org/docs/current/indexes-types.html). Doctrine ne prend pas en charge la création de types d'index prêts à l'emploi spécifiques au fournisseur de base de données (réf).

Pour résoudre ce problème, vous pouvez soit exécuter le DDL CREATE INDEX directement dans la base de données, soit écrire le DDL sur le fichier doctrine-migrations. Cette dernière option vous offre l'avantage de faciliter le déploiement ou l'annulation des modifications.

Peu importe la méthode que vous utilisez pour créer l'index personnalisé, Doctrine marquera toujours ces index personnalisés comme index non mappés. Par conséquent, si vous exécutez doctrine:schema:validate, vous obtiendrez une erreur indiquant que si votre base de données n'est pas synchronisée, le de même lors de l'exécution de doctrine:schema:update --dump-sql ou doctrine:migrations:diff, il vous montrera l'instruction DROP INDEX ... pour supprimer les index personnalisés.

Solution

J'utilise ces versions de package. (Je pense que la solution fonctionnera sur la même version majeure des packages) :

  • doctrine/dbal 4.0.4
  • doctrine/doctrine-bundle 2.12.0

J'ai trouvé plusieurs tutoriels pour gérer cela mais ce n'est pas satisfaisant :

  • https://www.liip.ch/en/blog/doctrine-and-generated-columns Cela ne fonctionnait plus car Doctrine DBAL supprime le gestionnaire d'événements sur DBAL 4. (ref)
  • https://medium.com/yousign-engineering-product/ignore-custom-indexes-on-doctrine-dbal-b5131dd22071 Cela affichait un message de dépréciation. La clé de configuration "platform_service" est obsolète depuis doctrine-bundle 2.9. DBAL 4 ne prendra plus en charge la définition d'une plate-forme personnalisée via les paramètres de connexion. (réf)

J'ai trouvé un problème GitHub concernant le remplacement de la configuration platform_service ici https://github.com/doctrine/DoctrineBundle/issues/1656.

La lecture de ces 2 pages m'a donné toutes les informations sur la façon d'utiliser une plateforme DBAL personnalisée via le middleware Doctrine :

  • https://github.com/doctrine/dbal/pull/5699
  • https://symfony.com/bundles/DoctrineBundle/current/middlewares.html

Enfin, après avoir fouillé dans le code source, j'ai trouvé la solution. Vous devez créer 4 fichiers, 2 fichiers concernent le middleware Doctrine et 2 autres fichiers concernent la plate-forme et le schéma Doctrine DBAL.

Modifiez l'espace de noms et le nom de la classe selon vos besoins.

<?php

declare(strict_types=1);

namespace App\Doctrine\DBAL\Middleware;

use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Middleware;

final class PostgreSQLPlatformMiddleware implements Middleware
{
    #[\Override]
    public function wrap(Driver $driver): Driver
    {
        return new PostgreSQLPlatformDriver($driver);
    }
}
<?php

declare(strict_types=1);

namespace App\Doctrine\DBAL\Middleware;

use App\Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\ServerVersionProvider;

final class PostgreSQLPlatformDriver extends AbstractDriverMiddleware
{
    #[\Override]
    public function getDatabasePlatform(ServerVersionProvider $versionProvider): AbstractPlatform
    {
        return new PostgreSQLPlatform();
    }
}

<?php

declare(strict_types=1);

namespace App\Doctrine\DBAL\Platforms;

use App\Doctrine\DBAL\Schema\PostgreSQLSchemaManager;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform as BasePostgreSQLPlatform;
use Doctrine\DBAL\Schema\PostgreSQLSchemaManager as BasePostgreSQLSchemaManager;
use Doctrine\DBAL\Schema\SchemaManagerFactory;

final class PostgreSQLPlatform extends BasePostgreSQLPlatform implements SchemaManagerFactory
{
    #[\Override]
    public function createSchemaManager(Connection $connection): BasePostgreSQLSchemaManager
    {
        return new PostgreSQLSchemaManager($connection, $this);
    }
}
<?php

declare(strict_types=1);

namespace App\Doctrine\DBAL\Schema;

use Doctrine\DBAL\Schema\PostgreSQLSchemaManager as BasePostgreSQLSchemaManager;

final class PostgreSQLSchemaManager extends BasePostgreSQLSchemaManager
{
    private const array IGNORED_INDEXES = [
        'index_name_1' => true,
        'index_name_2' => true,
    ];

    #[\Override]
    protected function _getPortableTableIndexesList(array $tableIndexes, string $tableName): array
    {
        $indexes = parent::_getPortableTableIndexesList($tableIndexes, $tableName);

        foreach (array_keys($indexes) as $indexName) {
            if (isset(self::IGNORED_INDEXES[$indexName])) {
                unset($indexes[$indexName]);
            }
        }

        return $indexes;
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn