首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将large Doctrine 2查询结果流式传输到输出

问将large Doctrine 2查询结果流式传输到输出
EN

Stack Overflow用户
提问于 2016-04-26 21:39:50
回答 1查看 1.5K关注 0票数 7

在我的项目中,我有一个API调用,它可能会返回数万条记录。

数据应该以一个块的形式返回。API设计不允许分页。

使用Doctrine 2DQL从MySQL查询源数据,每个记录由几个链接的对象组成。目前,查询结果大约是25'000条记录。我已经优化了SQL查询。它在毫秒内运行,所以无法在这里进行优化。

现在主要的问题是水合作用。我尝试过不同类型的hydrations,但处理这些数据量仍然需要很长时间。它也使用了太多的内存。

我的想法是在数据被加水后立即流式传输,然后在流式传输时立即删除数据。它不会减少完成请求的时间,但会减少内存使用,并减少响应开始前的时间。

在Doctrine 2中,有没有一种方法可以在每个结果行加水后执行一些操作?

也就是说,我做了一个大请求。我做了$qb->getQuery()->getResult()和Doctrine,而不是合并所有数据并在每条记录合并后返回结果,例如,将数据发送到STDOUT,并在数据被流式传输时立即删除对象。

PS:问题不是关于如何将此类查询的输出流式传输到HTTP。我能处理好。问题是我如何才能让Doctrine 2做我想做的事情。

EN

回答 1

Stack Overflow用户

发布于 2017-01-16 18:55:15

我的解决方案(包括CSV流以保证完整性):

代码语言:javascript
复制
function getExportableHead()
{
    // returns array of fields for headings
}

function getExportableRow($row)
{
    // returns array of values for a row
}

$qb = $this->em->getRepository(Item::class)->createSomeQueryBuilder();
$response = new StreamedResponse(function () use ($qb) {
    $data = $qb->getQuery()->iterate();
    $handle = fopen('php://output', 'w+');
    fputcsv($handle, getExportableHead(), ';');
    while (($object = $data->next()) !== false) {
        $row = getExportableRow($object[0]);
        fputcsv($handle, $row, ';');
        $this->em->detach($object[0]);
    }
    fclose($handle);
});
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="out.csv"');
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36866671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档