繁体   English   中英

Doctrine 夹具如何覆盖吹扫器 class?

[英]Doctrine fixtures how to override the purger class?

doctrine-fixture-bundle console doctrine:fixtures:load -n命令在这里定义:

https://github.com/doctrine/DoctrineFixturesBundle/blob/3.3.x/Command/LoadDataFixturesDoctrineCommand.php

我想知道如何扩展净化器并使用我自己的净化器 class? use Doctrine\Common\DataFixtures\Purger\ORMPurger;

例如使用这个净化器: https://gist.github.com/Ocramius/96206e3b39e96bd64bc5

您可以为您的 purger 创建服务定义,并使用--purger=my_purger调用 fixtures 命令,如文档中所述。

如评论中所述,您还可以装饰默认清除器。 为此,您可以将以下内容添加到您的services.yaml中:

doctrine.fixtures_load_command.custom:
  decorates: doctrine.fixtures_load_command
  class: Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand
  arguments:
    - '@doctrine.fixtures.loader'
    - '@doctrine'
    - { default: '@FixturesStuff\BrutalForeignKeyDisablingMySQLPurger' }

这会覆盖(装饰)fixtures 命令的服务定义。 并为该命令提供一个新的默认值。

这与 fixtures 命令的具体实现挂钩,因此它可能会在版本之间发生变化。 我使用的是 Symfony 5.4,对于您的特定版本,它可能看起来有点不同。

默认清除器由默认清除器工厂创建。 至少在 MySQL 上,使用默认清除器清除复杂的关系图很麻烦(请参阅尝试重新加载固定装置时的问题),您找到的解决方案是在删除期间禁用外键检查。

默认情况下,解决方案分为三个部分来执行此操作,而无需在每个控制台命令上显式指定清除器。

首先创建清除器,它简单地继承ORMPurger以不丢失任何功能(特别是排除):

<?php

namespace App\Doctrine\Fixtures;

use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManagerInterface;

class MySQLPurger extends ORMPurger
{
    /**
     * {@inheritDoc}
     */
    public function __construct(private readonly EntityManagerInterface $entityManager, array $excluded = [])
    {
        parent::__construct($this->entityManager, $excluded);
    }

    /**
     * Purges the MySQL database with temporarily disabled foreign key checks.
     *
     * {@inheritDoc}
     */
    public function purge(): void
    {
        $connection = $this->entityManager->getConnection();

        try {
            $connection->executeStatement('SET FOREIGN_KEY_CHECKS = 0');

            parent::purge();
        } finally {
            $connection->executeStatement('SET FOREIGN_KEY_CHECKS = 1');
        }
    }
}

然后创建创建净化器的工厂:

<?php

namespace App\Doctrine\Fixtures;

use Doctrine\Bundle\FixturesBundle\Purger\PurgerFactory;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\Common\DataFixtures\Purger\PurgerInterface;
use Doctrine\ORM\EntityManagerInterface;

class MySQLPurgerFactory implements PurgerFactory
{
    /**
     * Adapted from {@see \Doctrine\Bundle\FixturesBundle\Purger\ORMPurgerFactory} to return a MySQL-specific {@see PurgerInterface}.
     *
     * {@inheritDoc}
     */
    public function createForEntityManager(
        ?string $emName,
        EntityManagerInterface $em,
        array $excluded = [],
        bool $purgeWithTruncate = false
    ): PurgerInterface {
        $purger = new MySQLPurger($em, $excluded);
        $purger->setPurgeMode($purgeWithTruncate ? ORMPurger::PURGE_MODE_TRUNCATE : ORMPurger::PURGE_MODE_DELETE);

        return $purger;
    }
}

最后,覆盖服务配置中的默认清除器工厂:

services:
    # Override the default purger factory with the MySQLPurgerFactory, which skips foreign key checks.
    doctrine.fixtures.purger.orm_purger_factory:
        class: App\Doctrine\Fixtures\MySQLPurgerFactory
        tags:
            - { name: doctrine.fixtures.purger_factory, alias: default }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM