从 Django 查询集中获取值列表的最有效方法

3 python django list filter django-queryset

我可以看到很多不同的选择来执行此操作,并希望获得有关最有效或“最佳实践”方法的一些反馈。

我得到了一个带有 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)
Run Code Online (Sandbox Code Playgroud)

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

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

选项(我在搜索中看到过):

  1. 遍历查询集

例子:

gps_time = [lp.gps_time for lp in c_layer_points];
twtt = [lp.twtt for lp in c_layer_points];
Run Code Online (Sandbox Code Playgroud)
  1. 使用 values() 或 values_list()
  2. 使用迭代器()

最后,我想将其编码为 json 格式,如下所示:

{'gps_time':[list of all gps times],'twtt',[list of all twtt]}
Run Code Online (Sandbox Code Playgroud)

任何有关执行此操作的最佳方法的提示都会很棒,谢谢!

kar*_*ikr 5

您可能无法从 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')
Run Code Online (Sandbox Code Playgroud)

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

split_lst = zip(*c_layer_points)    
dict(gps_time=list(split_lst[0]), twtt=list(split_lst[1]))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,即使使用“.values_list()”(或“.iterator()”或我能告诉的其他任何内容),django 也会将所有记录读入内存。对于 SQL 性能来说非常好,但如果我们谈论的是大行,那么对于内存来说就不太好了。我的 python 进程使用了​​ > 300 MB 的 RAM。我最终使用“Paginator”来循环记录大块。内存与速度是一个权衡,我一次选择了 10,000 条记录。 (3认同)