0

私は現在djangoのプリフェッチ関連の問題があります。 は、例を与えるのは、それらのモデル Django prefetch_related大きなデータセット

from django.db import models 

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

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

のは、我々は、200のようなものをいくつかのクライアントを持っている想像してみましょう

を想像してみましょう、しかし、私たちは購入数百万を持って、彼らは多くを購入するには。

私はすべてのクライアントを表示するWebページおよび各クライアントの購入数を作成する必要がある場合、私はその

from django.db.models import Prefetch 
from .models import Purchase, Client 

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

のようなものを記述する必要がありますここでの問題は、私は大きな購入を照会するということですデータベースとそのクエリが1分よりもさらにを取る、あるいは悪化し、サーバー上のMemoryErrorを作成することがあります。

だから、私は

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

と、そのデータベースのバッチのみを選択しようとしましたが、我々が期待できるとして、Djangoはあまりそれを好きではないと

Traceback (most recent call last): 
    File "project/venv/lib/python3.6/site-packages/django/core/handlers/base.py", 
line 149, in get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "project/venv/lib/python3.6/site-packages/django/core/handlers/base.py", 
line 147, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "project/venv/lib/python3.6/site-packages/django/views/generic/base.py", 
line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "project/venv/lib/python3.6/site-packages/django/utils/decorators.py", l 
ine 67, in _wrapper 
    return bound_func(*args, **kwargs) 
    File "project/venv/lib/python3.6/site-packages/django/views/decorators/cache. 
py", line 57, in _wrapped_view_func 
    response = view_func(request, *args, **kwargs) 
    File "project/venv/lib/python3.6/site-packages/django/utils/decorators.py", l 
ine 63, in bound_func 
    return func.__get__(self, type(self))(*args2, **kwargs2) 
****************** login decorators, views, ... 
    File "project/***.py", line ***, in *** 
    for client in clients: 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 258, in __iter__ 
    self._fetch_all() 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 1076, in _fetch_all 
    self._prefetch_related_objects() 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 656, in _prefetch_related_objects 
    prefetch_related_objects(self._result_cache, self._prefetch_related_lookups) 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 1457, in prefetch_related_objects 
    obj_list, additional_lookups = prefetch_one_level(obj_list, prefetcher, lookup, level) 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 1556, in prefetch_one_level 
    prefetcher.get_prefetch_queryset(instances, lookup.get_current_queryset(level))) 
    File "project/venv/lib/python3.6/site-packages/django/db/models/fields/relate 
d_descriptors.py", line 539, in get_prefetch_queryset 
    queryset = queryset.filter(**query) 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 790, in filter 
    return self._filter_or_exclude(False, *args, **kwargs) 
    File "project/venv/lib/python3.6/site-packages/django/db/models/query.py", li 
ne 802, in _filter_or_exclude 
    "Cannot filter a query once a slice has been taken." 
AssertionError: Cannot filter a query once a slice has been taken. 

だから、例外のこの種を起動します今、私は本当の解決策はありません。私はdjango/db/models/query.py:258の__iter__関数が同じ振る舞いを持つ関数を作成しようとしていますが、それをページングするためにプリフェッチで制限されたセットを必要とするように構築されていますより平行した方法。

こうした種類のクエリを実行する「良い方法」はありますか?

答えて

0

私たちは200のようないくつかのクライアントを持っているとしますが、購入する商品は数多くあるので をたくさん買っています。

私はすべてのクライアントを表示するWebページおよび各クライアントの購入の 数を作成する必要がある場合は、...

私は、この機能を望むようにあなたの質問を解釈するつもりです。あなたは試してみました:

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/を参照してください。

+0

本当にありがとう、私が探していたもの、そして十分にマニュアルを読んでいないことを申し訳ありません^^ " –

関連する問題