2014-03-19 81 views
3

內執行命令一起對於發展,我們有,爲了重建分貝執行其他控制檯命令的單個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。*和遷移軟件包。

回答

0

我的猜測是,這是因爲您試圖一次多次運行遷移命令。 您可能想嘗試使用工作隊列系統,甚至有可能會有這樣的工具包。

+0

我會調查隊列,看看這是否是一個選項。我目前的解決這個問題的思想過程是使用php exec,但這只是感覺錯誤,並非Symfony做事的方式。 – MadManMonty

2

問題是應用程序對每個調用都使用相同的命令實例,Doctrine migrate命令不適用於此類環境。解決它的方法之一是克隆命令和工作直接與它的實例:

$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) 
5

我對symfony的2.6同樣的問題,並通過Alexei Tenitski描述的解決方案沒有奏效althought它似乎是一個有效的一個。 這是爲我工作的解決方案。

/** 
* 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將留在所有迭代一樣