【问题标题】:Symfony3: Doctrine batch processing with exceptions handlingSymfony3:带有异常处理的 Doctrine 批处理
【发布时间】:2017-01-31 09:57:31
【问题描述】:

我需要使用 Symfony3 命令从 Excel 文件中插入多个用户。我已经阅读了以下关于批处理的文章:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/batch-processing.html

我一直想知道是否有办法在查询失败时不停止刷新过程(例如对于非空列)。实际上,我希望能够在进行持久化之前不检查我的所有数据并让 Doctrine 继续插入,即使一个查询在 20 个查询的刷新中失败可以说。

感谢您的帮助。

亲切的问候,

【问题讨论】:

  • 基本没有。违反约束基本上意味着您不能再使用实体管理器。有一些关于改变这一点的讨论,但还没有。因此,在遇到异常时,您唯一的选择是创建一个全新的实体管理器对象。 ORM 并不是真正为批处理设置的。另一种方法是使用 Doctrine Database Abstraction Layer (DBAL)。
  • 感谢您的回答。所以我假设我的选择是在刷新之前验证所有内容,或者每个实体使用一次刷新并在每次失败时实例化一个新的实体管理器。对?如果我有 2000 个条目要连续存储,那么每个实体使用刷新会有什么问题?谢谢
  • 在每个实体之后刷新没有错,尽管您可能会遇到性能问题。但是2K实体应该没问题。 20K可能不是那么多。是的,在尝试坚持之前进行验证可能是值得的。

标签: exception-handling doctrine symfony batch-processing flush


【解决方案1】:

这个模板可以帮助你走得更远......

$batchSize = 20;
$currentSize = 0;

$data = [ .... ];
foreach ($data as $item) {
    $entity = new Entity();
    $entity->setProperty($item['property']);

    try {
        $currentSize++;
        $em->persist($entity);

        if ($batchSize% $currentSize === 0) {
            $em->flush();
            $em->clear();
        }
    } catch (\Doctrine\ORM\ORMException $e) {
        $currentSize--;
    }
}

$em->flush();
$em->clear();

【讨论】:

  • 谢谢。但似乎这不会告诉我哪个实体失败了。另外,如果一个实体刷新失败,整个批次都失败了,对吧?
  • 正如我所说,它只是模板。如果您想知道哪个实体导致失败,可以添加 $failedEntities = [];在循环上方并添加 $failedEntities[] = $entity;在渔获物内。添加 $container->get('doctrine')->resetManager(); $em = $container->get('doctrine')->getManager() 在 catch 内捕获失败后重新创建一个全新的 $em。
猜你喜欢
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 2011-04-08
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
相关资源
最近更新 更多