从Django Queryset中获取值列表的最有效方法

4
我可以看到有很多不同的选项来实现这个功能,希望能得到一些反馈关于最有效或“最佳实践”的方法。
我使用filter()获取Django Queryset。
c_layer_points = models.layer_points.objects.filter(location_id=c_location.pk,season_id=c_season.pk,line_path_id=c_line_path.pk,radar_id=c_radar.pk,layer_id__in=c_layer_pks,gps_time__gte=start_gps,gps_time__lte=stop_gps)

这个查询集可能非常大(数十万行)。

现在需要的是将其转换为列表并编码为JSON。

可选方案(我在搜索中看到的):

  1. 循环遍历查询集

示例:

gps_time = [lp.gps_time for lp in c_layer_points];
twtt = [lp.twtt for lp in c_layer_points];
  1. 使用values()或values_list()
  2. 使用iterator()

最终,我希望将其编码为json格式,如下所示:

{'gps_time':[list of all gps times],'twtt',[list of all twtt]}

任何关于如何最好地完成这个任务的提示都将非常有帮助,谢谢!

为什么不自己进行测量呢?import datetime; start = datetime.time(); <do your stuff> end = datetime.time(); print(end-start) - J0HN
我已经这样做了,并且将继续这样做。但是,我想听听其他人对于这里的“最佳实践”有何看法。特别是因为从效率的角度来看,其中几个选项几乎相同。 - user1676521
2个回答

8

ORM可能无法提供所需的格式。不过,您可以像这样高效地进行操作:

c_layer_points = models.layer_points.objects.filter(
    location_id=c_location.pk,
    season_id=c_season.pk, 
    line_path_id=c_line_path.pk,
    radar_id=c_radar.pk,
    layer_id__in=c_layer_pks,
    gps_time__gte=start_gps, 
    gps_time__lte=stop_gps
).values_list('gps_time', 'twtt')

现在将元组拆分为两个列表:(元组解包)

split_lst = zip(*c_layer_points)    
dict(gps_time=list(split_lst[0]), twtt=list(split_lst[1]))

3
请注意,即使使用.values_list()(或.iterator()或我所知的任何其他方法),Django仍会将所有记录读入内存。这对于SQL性能非常好,但如果涉及大型行,则对于内存来说可能不那么好。我的Python进程使用了> 300 MB的RAM。最终我使用Paginator来循环处理记录块。内存与速度之间需要权衡,我每次处理10,000条记录。 - James S

2
我建议您遍历查询集,并逐个从查询集中的元素确认json字典元素。通常,Django的查询集是惰性的,这意味着只有在访问它们时才会加载到内存中。如果您加载整个列表:gps_time = [lp.gps_time for lp in c_layer_points],那么您将在内存中拥有所有这些对象(成千上万)。通过简单迭代,您可以轻松解决这个问题。
for item in c_layer_points:
    #convert item to json and add it to the
    #json dict.

作为附注,Python 中行末不需要使用字符 ; :)
希望这可以帮到你!

好的,我会看一下这个。另外,我知道在MATLAB中使用分号是我的主要习惯(但这正在改变!),所以这只是一个不好的习惯! - user1676521
呵呵,我以前也写过 C++ 和 C# 的程序 ;) - Paulo Bu
我不确定这对我是否有效。实际上,我需要在数据上进行一些操作(意味着我必须将其作为列表加载到内存中)。例如,我需要根据c_layer_points中的项目执行一些插值操作。 - user1676521

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接