2016-10-30 4 views
2

큰 json 파일 (크기가 아닌 요소가 있음)이 있습니다. 그것은 30000 JSON 요소를 가지고 있으며 그것을 읽는대로 그것을 엔티티를 생성하려고합니다.symfony 컨트롤러를 사용하여 큰 JSON 파일 구문 분석

지금까지 Guzzle으로 파일을 읽었으며 충돌하기 전에 약 1500 개의 엔티티를 생성합니다. 나는 내가 틀린 길을 가고 있다고 느낍니다.

public function generateEntities(Request $request, $number) 
{ 
$client = new \GuzzleHttp\Client(); 
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://www.example.com/file.json'); 
$promise = $client->sendAsync($request)->then(function ($response) { 
    $batchSize = 20; 
    $i   = 0; 
    foreach (json_decode($response->getBody()) as $entityItem) { 
     $entity = new Entity(); 
     $entity->setEntityItem($entityItem->string); 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($entity); 
     if (($i % $batchSize) === 0) { 
      $em->flush(); // Executes all updates 
     } 
     $i++; 
    } 
    $em->flush(); 
}); 
$promise->wait(); 
return $this->redirect($this->generateUrl('show_entities')); 
} 

는 내가 자주 엔티티 관리자를 삭제해야 연구에서 밖으로 일했다, 그래서 나는 그것을 만든 매 20 개체를 세척하는 등 크기 조정 배치에 추가 :

여기 내 코드입니다. 이것은 도움이되었지만 전체 30000 파일을로드하기에 충분하지 않습니다.

어쩌면 저는 완전히 잘못되어 다른 방식으로 처리해야합니까?

누군가가 올바른 방향으로 나를 가리키게 할 수 있습니까? 나는 그것을 스스로 해결할 수있어서 기쁩니다. 여기서부터 좀 더 확신 할 수는 없습니다.

감사합니다.

+0

먼저 코드를 Symfony Console Command로 옮깁니다. 콘솔 명령은 메모리 제한 (afaik)에 의해 제한되지 않으므로 완료에 더 많은 시간을 줄 수 있어야합니다. 어떤 특별한 이유로 액션 컨트롤러가 필요합니까? –

+0

@JovanPerovic 답장을 보내 주셔서 감사합니다. 아니, 그냥 그것을 처리하는 가장 좋은 방법이라고 생각했습니다. (최근 Symfony를 사용하기 시작했습니다.) 데이터베이스에 모든 것을로드 할 필요는 없습니다. –

+0

전반적으로 귀하의 접근 방식은 건전 해 보입니다. 나는 이것이 Doctrine 부분을 쓸모 없게 만들었지 만, 당신은'ORM' 대신에'DBAL'을 사용하려고 생각 했는가? 기본적으로 엔터티 대신 쿼리를 직접 구성 할 수 있습니다. 개인적으로, 나는 많은 양의 데이터를 운반 할 때 그 방법을 매우 좋아한다 ... –

답변

2

두 가지 방법으로 처리 행위를 향상시킬 수

012 :
public function generateEntities(Request $request, $number) 
{ 
    set_time_limit(0); // set to zero, no time limit is imposed 

2) 무료 많은 메모리는 데이터베이스에 데이터를 플러시하고 다음과 같이/무료 메모리를 분리 각의 상호 작용에 대한 가능하다

희망 도움말

1

모든 30000 엔티티가 메모리에서 관리되므로 스크립트의 메모리가 부족합니다. 매니저가 주기적으로 엔티티를 분리하여 "가비지 콜렉션"되었는지 확인해야합니다. 배치 플러시 블록에서 $em->clear();을 사용하여 메모리가 모두 소모되지 않도록하십시오. 자세한 내용은 Doctrine page on batch operations을 참조하십시오.

$em->clear()은이 루프에서 사용하는 관리자뿐만 아니라 관리자로부터 모든 엔터티를 분리합니다.

1) 증가 기능 set_time_limit와 컨트롤러 액션의 실행 시간 제한, 그래서 컨트롤러의 첫 번째 줄이를 넣어 :