5

对于开发,我们有一个 Symfony 控制台命令,它执行其他控制台命令以重建数据库、运行固定装置等。

作为该过程的一部分,我需要运行一些精心挑选的学说迁移命令,但由于某种原因,我无法在同一进程中运行多个执行命令。

为了确认,我可以手动运行这些任务而不会出现问题,并且可以在控制台执行中运行其中一个命令,然后手动运行另一个命令而不会出现问题。

          $this->getApplication()->run(new ArrayInput(array(
            'command' => 'doctrine:migrations:execute',
            'version' => '20140310162336',
              '--no-interaction' => true
                )), $output);

          $this->getApplication()->run(new ArrayInput(array(
            'command' => 'doctrine:migrations:execute',
            'version' => '20140310170437',
              '--no-interaction' => true
                )), $output);

返回的错误是:

[Doctrine\DBAL\Migrations\MigrationException]
Migration version 20140310162334 already registered with class Doctrine\DBAL\Migrations\Version

作为存在的第一个版本文件的版本,可以确认该版本不在 migration_versions 表中,在这种情况下也不需要。建议它只是加载到迁移对象中。

如果我做错了什么,如果这可能是某个地方的错误,任何人都可以提供输入。

使用 dev-master 运行 Symfony 2.2.* 和迁移包。

4

3 回答 3

5

我在 symfony 2.6 上遇到了同样的问题,Alexei Tenitski描述的解决方案没有用,尽管它似乎是一个有效的解决方案。这是对我有用的解决方案。

/**
 * Loop thorugh the config and path config for migrations 
 * and execute migrations for each connection
 */
foreach (array_keys($this->migrationsConfig) as $configEm) {
    if (
        (empty($ems) || in_array($configEm, $ems))
        && !in_array($configEm, $ignoreEms)
    ) {
        try {
            // new instance of the command you want to run 
            // to force reload MigrationsConfig
            $command = new MigrateSingleCommand($this->migrationsConfig);
            $command->setApplication($this->getApplication());
            $arguments = [
                'command' => $commandString,
                '--em' => $configEm,
            ];
            $input = new ArrayInput($arguments);

            $command->run($input, $output);

        } catch (\Exception $e) {
            $output->writeln(sprintf("<error>Error: %s</error>", $e->getMessage()));
        }
    }
}

如果您使用$this->getApplication()->run()它,它将只从$this->application->commands命令初始化一次的位置获取命令(当命令调用被初始化时),因此 MigrationsConfig 在所有迭代中都将保持不变。

于 2015-12-29T13:18:23.760 回答
4

问题是应用程序对每个调用都使用相同的命令实例,而 Doctrine 迁移命令并不是为在这种环境中工作而设计的。解决它的一种方法是克隆命令并直接使用它的实例:

$commandName = 'doctrine:migrations:execute';

$prototypeCommand = $this->getApplication()->get($commandName);

// This is required to avoid merging of application definition for each cloned command
$prototypeCommand->mergeApplicationDefinition();

// Create a clone for a particular run
$command1 = clone $prototypeCommand;

// Run the command with specific params
$command1->run($input1, $output)

// Create another clone
$command2 = clone $prototypeCommand;

// Run the command with another set of params
$command2->run($input2, $output)
于 2014-12-16T19:28:00.760 回答
0

我的猜测是,这是因为您尝试一次多次运行迁移命令。您可能想尝试使用工作队列系统,甚至可能有一个包可以做到这一点。

于 2014-03-19T14:31:19.763 回答