【发布时间】:2015-10-13 21:44:17
【问题描述】:
好的,所以我在从数据生成 CSV 文件时遇到问题。
我有一个大约 6,000 个对象的列表。这些对象就像自定义表单, 所以每个对象都有许多与之关联的字段。例如,请求可能包含姓名、年龄、电话号码等。在这种情况下,每个请求都具有相同的字段。所以每个表单都与这些字段有一对多的关系。
所以我将这个自定义表单和一些标准的东西作为 ValuesQuerySet 抓取,然后抓取与该表单关联的所有字段。并将它们添加到每一行。最后,我使用字典编写器将数据写入 csv。这一切都很好,但是性能很糟糕。完成我的 6,000 条记录,每条记录大约有 15 个自定义字段,大约需要 90 秒。(这会触发超时错误)。我需要一些方法来加快速度。
我的代码看起来像这样......
forms = SomeForm.objects.filter(created_by=user).values('value1', 'value2', 'etc...')
for form in forms:
id = form['id']
fields = Fields.objects.filter(Form_id=id).values('value', 'field__label')
for field in fields:
label = field['form_field__label']
value = field['value']
form[label] = value
writer = csv.DictWriter(response, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(forms)
一些代码被删除,但这是它的要点。 如果您无论如何都能想到加快速度,或者可能有另一种方法来处理它,我将不胜感激。
【问题讨论】:
-
您是否尝试过将
created_by字段设为索引?这可能会提高性能... -
是的,这是我想到的事情之一。经过一番研究,在 django 中,当您使用外键定义模型时,它会自动设置 db_index=True。不过感谢您的建议。
-
如果你没有注意到,django 在查询集上有
select_related和prefetch_related函数,可以在一个查询中加载一些关系并将它们放入查询集缓存中。也许这会有所帮助。 -
无论如何,这不是一项简单的任务,任何处理这么多记录的任务在 celery 任务中应该会更好
-
正如 Alvaro 所说,这不是您应该在请求中执行的操作。检查 celery 并将其作为异步任务运行,一旦完成,您可以通知用户文件的位置。