如何在不进行评估的情况下拆分Django查询集?

bmj*_*owe 4 python django performance django-models django-queryset

我正在处理超过500万个项目Queryset(对于批量ML目的),我需要拆分查询集(所以我可以执行多线程操作)而不评估查询集,因为我只需要访问查询集中的每个项目因此我不想缓存评估原因的查询集项.

是否可以将项目选择到一个查询集中并将其拆分而不进行评估?或者我将不得不通过使用Limits [:size]查询多个查询集来实现此行为?

注意:我知道可以使用Iterable来循环查询集而不进行评估,但我的问题与如何拆分查询集(如果可能)然后在每个拆分的查询集上运行迭代相关.

小智 6

如果您的 django 版本是1.11或低于1.101.9等版本,则使用paginator.page(page_no)但要小心,当发现无效/未找到页面时,这可能会引发 InvalidPage 异常。

对于版本<= 1.11,使用以下代码:

from django.core.paginator import Paginator

qs = MyModel.objects.all()
paginator = Paginator(qs, 20)

for page_no in paginator.page_range:
    current_page = paginator.page(page_no)
    current_qs = current_page.object_list
Run Code Online (Sandbox Code Playgroud)

如果您使用 django 版本 >= 2.0,请改用paginator.get_page(page_no),但您也可以使用paginator.page(page_no)

对于>= 2.0 的版本,请使用以下代码:

from django.core.paginator import Paginator

qs = MyModel.objects.all()
paginator = Paginator(qs, 20)

for page_no in paginator.page_range:
    current_page = paginator.get_page(page_no)
    current_qs = current_page.object_list
Run Code Online (Sandbox Code Playgroud)

根据django文档使用paginator.get_page(page_no)的好处如下:

返回有效页面,即使页面参数不是数字或不在范围内。

而在paginator.page(page_no)的情况下,如果 page_no 不是数字或超出范围,您必须手动处理异常。


Dhi*_*aTN 5

Django提供了一些类来帮助您管理分页数据 - 即分布在多个页面上的数据,具有"上一个/下一个"链接:

from django.core.paginator import Paginator

object_list = MyModel.objects.all()
paginator = Paginator(object_list, 10) # Show 10 objects per page, you can choose any other value

for i in paginator.page_range(): # A 1-based range iterator of page numbers, e.g. yielding [1, 2, 3, 4].
    data = iter(paginator.get_page(i))
    # use data
Run Code Online (Sandbox Code Playgroud)