首页 > 解决方案 > 在夹具中执行 Symfony 4 自定义命令

问题描述

我在我的 symfony 项目中有一个自定义命令,用于使用应用程序在开发和生产环境中工作所需的默认数据填充数据库。

对于开发环境,我有一个依赖于这些默认公共数据的夹具脚本。我正在尝试在夹具脚本中调用我的自定义 Symfony 命令,以便我确定拥有正确加载我的夹具所需的数据。

这是我在“伪脚本”中的自定义命令app:db:populate,只是创建了一堆实体,持久化和刷新。当我通过调用它时,我的自定义命令工作正常php bin/console app:db:populate

protected function execute(InputInterface $input, OutputInterface $output)
{
    // Creating a bunch of default entities, persist them and flush

    $data = new MyDefaultEntity();
    // ...
    $this->manager->persist($data);
    // ...
    $this->manager->flush();
}

然后,在我的夹具脚本中,我想先调用app:db:populate,因为夹具依赖于这些数据。所以我尝试使用Process该类以这种方式执行我的脚本:

public function load(ObjectManager $manager)
{
    // Execute the custom command
    $cmd = 'php bin/console app:db:populate';
    $process = new Process($cmd);
    $process->run(function ($type, $buffer) {
        if (Process::ERR === $type) {
            echo 'ERR > '.$buffer;
        } else {
            echo 'OUT > '.$buffer;
        }
    });

    // Then load the fixtures !
    // ...
}

自定义命令似乎执行良好,直到$this->manager->flush();

我的控制台中有以下错误(帖子的数据被混淆了):

In AbstractMySQLDriver.php line 36:

  An exception occurred while executing 'INSERT INTO ....(..., ..., ...) VALUES (?, ?, ?)' with params ["...", "...", "..."]:

  SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction

我不知道如何处理这个错误......为什么通过经典控制台调用使用该命令时可以正常工作以及为什么它不能在 Process 中工作?

如果您有任何其他策略可以帮助我实现目标,我正在倾听:)

祝你今天过得愉快 !

标签: symfonyprocesscommandlockingfixtures

解决方案


所以,简短的回答是

引用 Symfony 文档:

您可能需要执行一些仅在控制台命令中可用的功能。通常,您应该重构命令并将一些逻辑移动到可以在控制器中重用的服务中。

我最终创建了一个服务类来处理所有 app:db:populate 逻辑(读取一个 json 文件并在数据库中插入基本的应用程序实体)。然后我在 app:db:populate 执行方法和 AppFixtures 加载方法中调用此服务。

希望这会对某人有所帮助。


推荐阅读