【问题标题】:Doctrine clear() and many to one relation教义 clear() 和多对一关系
【发布时间】:2016-01-13 08:26:55
【问题描述】:

我需要从 csv 文件中导入大量数据(大约 1m 条记录)。 为了避免内存泄漏,我尝试从学说文档中批量插入:

$batchSize = 20;
for ($i = 1; $i <= 10000; ++$i) {

    //code

    $em->persist($user);
    if (($i % $batchSize) === 0) {
        $em->flush();
        $em->clear(); // Detaches all objects from Doctrine!
    }
}
$em->flush(); //Persist objects that did not make up an entire batch
$em->clear();

问题是我的插入包含“多对一”关系,并且每次我使用 clear() 对象时都会出现来自该关系的重复条目。

是否有可能分离实体并避免重复?

【问题讨论】:

  • 附带说明:在进行大批量操作时,始终建议不要使用 Doctrine。您应该将 PDO 用于此类任务。

标签: php symfony doctrine-orm many-to-one


【解决方案1】:

是的,有。您需要执行智能清洁。这意味着您提供要清除的实体类型。示例:

$em->clear(SomeEntity::class);
$em->clear(OtherEntity::class);

这将从 EM 中仅删除那些类型,并保留其他所有内容。通过这种方式,您可以重用那些其他对象。

【讨论】:

【解决方案2】:

使用 ORM 导入大数据非常耗时且耗费内存。我从来没有找到用 Doctrine 进行快速和理智导入的方法。除了我以这种方式进行的导入之外,还有一个要维护的 PITA。

经过多年导入数据,我发现最有效的方法是:

  • CSV 导入临时表(MySQL 中的 LOAD DATA INFILE 或 pgsql 中的 COPY)
  • 进行插入或更新查询(INSERT INTO .. SELECT .. ON DUPLICATE KEY in MySQL)
  • 根据复杂程度在 SQL 或 PHP 中执行更具体的操作

这样我可以在几秒钟内导入十几个大的 CSV 文件。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多