Django prefetch_related一个大型数据集

时间:2017-05-12 18:28:53

标签: python django postgresql django-models query-optimization

我现在对django的预取相关问题。 举个例子,让我们想象那些模型

df = df.astype({'sensorA': 'int32', 'sensorB': 'int32'}) #etc

让我们假设我们有一些客户,比如200,但他们买了很多,所以我们有数百万的购买。

如果我必须创建一个显示所有客户的网页和每个客户的购买数量,我将不得不写出类似的东西

from django.db import models

class Client(models.Model):
    name = models.CharField(max_length=255)

class Purchase(models.Model):
    client = models.ForeignKey('Client')

这里的问题是我将查询大型购买数据库,该查询可能需要超过一分钟,或者更糟糕的是在服务器上创建MemoryError。

所以,我试图用

只选择一批那个数据库
from django.db.models import Prefetch
from .models import Purchase, Client

purchases = Purchase.objects.all()
clients = Client.prefetch_related(Prefetch('purchase_set', queryset=purchases))

但正如我们所料,Django并不喜欢它并发起这种异常

 purchases = Purchase.objects.all()[:9]

所以现在,我没有真正的解决方案。我正在寻找如何构建django / db / models / query.py:258中的__iter__函数来尝试创建具有相同行为但在预取中需要有限集合以便对其进行分页的函数,并在一种更平行的方式。

有没有“好方法”来进行这类查询?

1 个答案:

答案 0 :(得分:1)

  

让我们想象一下,我们有几个客户,比如200,但是他们买了   很多,所以我们有数百万的购买。

     

如果我必须创建一个显示所有客户端和网站的网页   每个客户的购买数量,......

我会将您的问题解释为需要此功能。你试过了吗?

from django.db.models import Count
clients = Client.objects.annotate(num_purchases=Count('purchase'))
clients[0].num_purchases

如果您想要排序并获得最高的采购客户,您也可以这样做:

clients = Client.objects.annotate(num_purchases=Count('purchase')).order_by('-num_purchases')[:5]

有关更多功能,请参阅https://docs.djangoproject.com/en/1.11/topics/db/aggregation/