ホームページ >バックエンド開発 >PHPチュートリアル >Doctrine DBAL 4 のカスタムインデックスを無視する

Doctrine DBAL 4 のカスタムインデックスを無視する

王林
王林オリジナル
2024-07-28 00:10:32453ブラウズ

Ignore custom indexes on Doctrine DBAL 4

エンティティ ファイルの #[ORMIndex(fields: ['fieldName'] 属性を使用してデータベース インデックスを作成できます。残りのインデックスの管理は Doctrine が行いますが、私が行います。それについては話さないでください

プロジェクトが成長したり、特定の要件が必要になったりすると、GIST、GIN、BRIN などのカスタム インデックス タイプの使用が必要になる場合があります (https://www.postgresql.org/docs/current/indexes-types.html)。 Doctrine は、すぐに使えるデータベースベンダー固有のインデックスタイプの作成をサポートしていません (参照)。

この問題に取り組むには、CREATE INDEX DDL をデータベースに直接実行するか、DDL を doctrine-migrations ファイルに書き込むことができます。後者のオプションには、変更のデプロイまたはロールバックが容易になるという利点があります。

カスタムインデックスの作成にどの方法を使用しても、Doctrine は常にそれらのカスタムインデックスをマップされていないインデックスとしてマークするため、 doctrine:schema:validate を実行すると、データベースが同期していないことを示すエラーが表示されます。 doctrine:schema:update --dump-sql または doctrine:migrations:diff の実行中も同様に、カスタム インデックスを削除するための DROP INDEX ... ステートメントが表示されます。

解決

私はこれらのパッケージ バージョンを使用しています。 (このソリューションはパッケージの同じメジャー バージョンで動作すると思います):

  • ドクトリン/dbal 4.0.4
  • ドクトリン/ドクトリンバンドル 2.12.0

これを処理するためのチュートリアルをいくつか見つけましたが、満足のいくものではありません:

  • https://www.liip.ch/en/blog/doctrine-and-generated-columns Doctrine DBAL が DBAL 4 のイベント マネージャーを削除したため、これは機能しなくなりました。(ref)
  • https://medium.com/yousign-engineering-product/ignore-custom-indexes-on-doctrine-dbal-b5131dd22071 これは非推奨メッセージを示していました。「platform_service」設定キーは doctrine-bundle 2.9 以降非推奨になりました。 DBAL 4 では、接続パラメータによるカスタム プラットフォームの設定はサポートされなくなります。 (参考)

ここ https://github.com/doctrine/DoctrineBundle/issues/1656 で、platform_service 構成の置換に関する GitHub の問題を見つけました。

これらの 2 ページを読むことで、Doctrine ミドルウェアを介してカスタム DBAL プラットフォームを使用する方法に関するすべての情報が得られました。

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

最後に、ソースコードを詳しく調べた結果、解決策が見つかりました。 4 つのファイルを作成する必要があります。2 つのファイルは Doctrine ミドルウェアに関するもので、他の 2 つのファイルは Doctrine DBAL プラットフォームとスキーマに関するものです。

必要に応じて名前空間とクラス名を変更します。

<?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;
    }
}

以上がDoctrine DBAL 4 のカスタムインデックスを無視するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。