2016-10-30 13 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

次の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とコントローラアクションの実行の時間制限、そのコントローラの最初の行としてこれを置く:

関連する問題