2015-09-15 3 views
1

Я пытаюсь создать много одного и того же объекта в моей базе данных, чтобы вставить некоторых пользователей, точнее. Во-первых, я попытался очистить менеджер объектов после каждого цикла, но это не сработало. После некоторых исследований я узнал, что могу делать это с помощью партий, поэтому я попытался промыть каждые 15 циклов, но я все равно получаю тайм-аут через 30 секунд (около 180 запросов). Разве они не бывают быстрыми или почти мгновенными для числа, равного 200-250? Как я могу сделать это не время и вставить их быстрее?Doctrine in Symfony2 множественные вставки тайм-аут

Что делает моя функция, это сделать запрос к randomuser.me и получить json пользователей. Я извлекаю эти данные в массив и использую его для заполнения моей информации о пользователях. У меня также есть массив $ fields где-то, у которого есть определенные медицинские поля (не будет размещать его здесь, поскольку это всего лишь массив простого текста). Он также добавляет соответствующую запись настроек для записи пользователя (содержащую поле, в котором работает медик, и его изображение).

public function generateAction() 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $generated = 0; 

     $url = "https://randomuser.me/api/?results=250&nat=us"; 
     $str = file_get_contents($url); 
     $medics = json_decode($str); 


    $medicsgruop = $this->getDoctrine()->getRepository('MedAppBundle:Group')->findOneBy(array('name' => 'medics')); 

    if (!$medicsgruop) { 
     $medicsgruop = new Group('medics'); 
     $medicsgruop->addRole('ROLE_MEDIC'); 
     $em->persist($medicsgruop); 
     $em->flush(); 
    } 
     $batchSize = 15; 
     foreach ($medics->results as $i => $medic) { 

      if ($this->fields[$i]) { 
       $field = $this->fields[$i]; 
      } else { 
       $field = array_rand($this->fields); 
      } 

      $fname = $medic->user->name->first; 
      $lname = $medic->user->name->last; 

      $image = $medic->user->picture->large; 
      $email = $medic->user->email; 

      $user = new User(); 
      //user 
      $user->setUsername($lname.$fname); 
      $user->setFirstname($fname); 
      $user->setLastname($lname); 
      $user->setEmail($email); 
      $user->setEnabled(true); 
      $user->setPlainPassword($fname.$lname); 
      //group 



      $user->addGroup($medicsgruop); 
      $em->persist($user); 
      //MEDIC SETTINGS 
      $medsett = new MedicSettings(); 
      $medsett->setField($field); 
      $medsett->setProfile($image); 
      $medsett->setMedic($user); 
      $em->persist($medsett); 


      if (($i % $batchSize) == 0) { 
       $em->flush(); 
       $em->clear(); 
      } 
     } 
     $em->flush(); 
     $em->clear(); 
     return $this->render(
      '@MedApp/Admin/generatemedics.html.twig', 
      array('generated' => $generated, 'medics' => 'asd') 
     ); 
    } 

При использовании метода пакетной, около 40 пользователей добавляются в моей базе данных, но он останавливается после того, как максимальное время выполнения достигается. Что я делаю не так?

+2

Может быть, просто добавить http://php.net/manual/ru/function.set-time-limit.php – user2883814

+0

Это не вставит все мои записи, он остановится после достижения. Я ищу способ вставить все, что есть. –

+0

нет другого шанса, поскольку в доктрине нет реальной объемной вставки (используйте собственный запрос, специфичную для db функциональность или что-то подобное). единственное, что вы могли бы проверить в дополнение к уже имеющемуся правильному подходу к проверке: проверьте, находитесь ли вы в среде разработчиков, все журналы регистрации отладки и т. д. - это потребляет много времени. Когда я делал что-то подобное в «производстве», количество потребляемого времени резко сокращалось. – LBA

ответ

0

Использование предложения malcolm для использования команды Client из symfony. Однако команда все еще работает медленно. Как ~ 1 секунда для каждого пользователя. И они вставляются в DB 15 за раз, за ​​пакет.

class GenMedicsCommand extends ContainerAwareCommand 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    protected function configure() 
    { 
     $this 
      ->setName('doctrine:generate:medics') 
      ->setDescription('Generate medics group, users, group-users, medic settings') 
      ->addArgument(
       'number', 
       InputArgument::REQUIRED, 
       'How many medics to generate?' 
      ); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     $number = $input->getArgument('number'); 
     $this->generate($number,$output); 

    } 


    protected $fields = array(
     'Abdominal Radiology Radiology-Diagnostic', 
     'Addiction Psychiatry Psychiatry', 
     'Adolescent Medicine Pediatrics'  
    ); 

    //generate random medics for the win 
    public function generate($nr, OutputInterface $output) 
    { 


     $em = $this->getContainer()->get('doctrine.orm.entity_manager'); 
     $doctrine = $this->getContainer()->get('doctrine'); 

     $generated = 0; 

     $url = "https://randomuser.me/api/?results=".$nr."&nat=us"; 
     $str = file_get_contents($url); 
     $medics = json_decode($str); 

     $medicsgruop = $doctrine->getRepository('MedAppBundle:Group')->findOneBy(array('name' => 'medics')); 

     if (!$medicsgruop) { 
      $medicsgruop = new Group('medics'); 
      $medicsgruop->addRole('ROLE_MEDIC'); 
      $em->persist($medicsgruop); 
      $em->flush(); 
     } 

     $batchSize = 15; 
     foreach ($medics->results as $i => $medic) { 
     // set_time_limit(2); 


      $randkey = array_rand($this->fields); 
      $field = $this->fields[$randkey]; 

      $fname = $medic->user->name->first; 
      $lname = $medic->user->name->last; 

      $image = $medic->user->picture->large; 
      $email = $medic->user->email; 

      $user = new User(); 
      //user 
      $user->setUsername($lname.$fname); 
      $user->setFirstname($fname); 
      $user->setLastname($lname); 
      $user->setEmail($email); 
      $user->setEnabled(true); 
      $user->setPlainPassword($fname.$lname); 
      //group 


      $user->addGroup($medicsgruop); 

      $em->persist($user); 
      //MEDIC SETTINGS 
      $medsett = new MedicSettings(); 
      $medsett->setField($field); 
      $medsett->setProfile($image); 
      $medsett->setMedic($user); 
      $em->persist($medsett); 
      $output->write(array($i+1,'|',$fname,'|',$lname,'|',$field,'|',$email,'|',$image)); 
      $output->writeln(''); 
      if (($i % $batchSize) == 0) { 
       $em->flush(); 
       // $em->clear(); 
      } 
     } 
     $em->flush(); 
     $em->clear(); 


     $output->writeln('done'); 
    } 

}