2014-08-29 4 views
0

Symfony2 컨트롤러에서 $em->flush()에 관한 질문이 있습니다. 내 테이블에 ~ 40,000 VEHICULES를 가지고 있기 때문에Symfony2 flush() 엔티티

$v = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")->findAll(); 
foreach ($v as $vehicule) { 
    [...] 
    $somme = {"compute before"}; 
    $veh = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")->find($vehicule->getIdvehicules()); 
    $veh->setTaxeadditionnelle($somme); 
    $em->flush(); 
    $total++; 
} 

그래서,이 루프를 실행하기 위해, 내 스크립트는 시간이 오래 걸릴.

나는 각 루프에서 $em->flush()

$v = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")->findAll(); 
$k = 0; 
foreach ($v as $vehicule) { 
    [...] 
    $somme = {"compute before"}; 
    $veh[$k] = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")->find($vehicule->getIdvehicules()); 
    $veh[$k]->setTaxeadditionnelle($somme); 
    $total++; 
} 
$em->flush(); // Flush all of vehicule update ?! 
unset($veh); 

이 버전은 작업 할 수 ... 필요하지 않습니다 가정? 감사합니다.

+1

초기 생각은 ORM이 부적절한 경우입니다. Doctrine 쿼리 작성기를 사용하여 DBAL 계층에 직접 말할 수 있습니다. – lonesomeday

+0

Doctrine 문서에서 일괄 처리에 대한 정보가 있습니다 - http://docs.doctrine-project.org/en/2.0.x/reference/batch-processing.html#bulk-inserts – qooplmao

+1

@Prisoner'persist'는 지속성을위한 것입니다 새로운 엔티티는 이미 지속 된 엔티티를 업데이트 할 때 사용되어서는 안됩니다. –

답변

0

대신 다음과 같이 한 번에 20 개씩 플러시 할 수 있습니다. 이것은 훨씬 빠르게 작동합니다.

$v = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")->findAll(); 
$index = 0; 
foreach ($v as $vehicule) { 
    [...] 
    $somme = {"compute before"}; 
    $veh = $em->getRepository("ApplicationAdminBundle:VehiculeCompute")-> 
          find($vehicule->getIdvehicules()); 
    $veh->setTaxeadditionnelle($somme); 
    $em->persist($veh); 
    if($index%20==0) 
     $em->flush(); 
    $index++; 
} 
$em->flush(); 
+0

persit()없이'-> find()'엔티티를 업데이트하기 때문에 – RudySkate

1

대신 많은 양의 데이터에서 동일한 작업을 수행 할 수있는 엔티티 관리자를 사용하는 자사의은에 그렇지

$em 
    ->getRepository('Foo') 
    ->createQueryBuilder() 
    ->update() 
    ->field('bar')->set('value') 
    ->getQuery() 
    ->execute(); 

같은 쿼리 빌더 업데이트 플러시 사용하는 경우 (알아서)을 처리하는 것이 좋습니다 큰 배열. 이 사용법에 대해 몇 가지 문제가 있었고 array_chunk를 사용하고 100 개 이하의 항목을 플러시하여 해결했습니다.

+0

Thx. queryBuilder 인스턴스로이 프로세스를 알고 있습니다. 그걸로 해보겠습니다 ^^ – RudySkate

+0

제 편집 좀보세요;) –

0

감사합니다! $em->flush()이 루프 외부에 있고 각 엔터티가 $veh[] 인 배열로되어 있으면 모두 OK입니다!