mirror of https://github.com/django/django.git
Refs #33646 -- Reduced sync_to_async hops on async QuerySet iteration.
Until we add support for truly asynchronous database backends it's actually detrimental to have complete set retrieval require multiple hops between sync and async emulated contexts via asgiref. By defaulting to sending the whole sync _fetch_all() to the current context thread pool we reduce unncessary work when dealing with large result sets since the queryset cannot be iterated anyway before all results are retrieved and cached.
This commit is contained in:
parent
37470bbd90
commit
1109e66990
|
@ -398,7 +398,7 @@ class QuerySet:
|
|||
# Remember, __aiter__ itself is synchronous, it's the thing it returns
|
||||
# that is async!
|
||||
async def generator():
|
||||
await self._async_fetch_all()
|
||||
await sync_to_async(self._fetch_all)()
|
||||
for item in self._result_cache:
|
||||
yield item
|
||||
|
||||
|
@ -1842,12 +1842,6 @@ class QuerySet:
|
|||
if self._prefetch_related_lookups and not self._prefetch_done:
|
||||
self._prefetch_related_objects()
|
||||
|
||||
async def _async_fetch_all(self):
|
||||
if self._result_cache is None:
|
||||
self._result_cache = [result async for result in self._iterable_class(self)]
|
||||
if self._prefetch_related_lookups and not self._prefetch_done:
|
||||
sync_to_async(self._prefetch_related_objects)()
|
||||
|
||||
def _next_is_sticky(self):
|
||||
"""
|
||||
Indicate that the next filter call and the one following that should
|
||||
|
@ -2025,12 +2019,6 @@ class RawQuerySet:
|
|||
if self._prefetch_related_lookups and not self._prefetch_done:
|
||||
self._prefetch_related_objects()
|
||||
|
||||
async def _async_fetch_all(self):
|
||||
if self._result_cache is None:
|
||||
self._result_cache = [result async for result in RawModelIterable(self)]
|
||||
if self._prefetch_related_lookups and not self._prefetch_done:
|
||||
sync_to_async(self._prefetch_related_objects)()
|
||||
|
||||
def __len__(self):
|
||||
self._fetch_all()
|
||||
return len(self._result_cache)
|
||||
|
@ -2047,7 +2035,7 @@ class RawQuerySet:
|
|||
# Remember, __aiter__ itself is synchronous, it's the thing it returns
|
||||
# that is async!
|
||||
async def generator():
|
||||
await self._async_fetch_all()
|
||||
await sync_to_async(self._fetch_all)()
|
||||
for item in self._result_cache:
|
||||
yield item
|
||||
|
||||
|
|
Loading…
Reference in New Issue