[英]How should one implement a custom Doctrine purger when using Symfony 6?
[英]Doctrine fixtures how to override the purger class?
从doctrine-fixture-bundle
console doctrine:fixtures:load -n
命令在这里定义:
我想知道如何扩展净化器并使用我自己的净化器 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.