私は現在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__関数が同じ振る舞いを持つ関数を作成しようとしていますが、それをページングするためにプリフェッチで制限されたセットを必要とするように構築されていますより平行した方法。
こうした種類のクエリを実行する「良い方法」はありますか?
本当にありがとう、私が探していたもの、そして十分にマニュアルを読んでいないことを申し訳ありません^^ " –