Skip to content

Commit 2b6de88

Browse files
committed
Asynchronous version of prefetch method
1 parent e657f7f commit 2b6de88

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

docs/peewee_async/api.rst

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Select, update, delete
1111
.. autofunction:: peewee_async.create_object
1212
.. autofunction:: peewee_async.delete_object
1313
.. autofunction:: peewee_async.update_object
14+
.. autofunction:: peewee_async.prefetch
1415

1516
Transactions
1617
------------

peewee_async.py

+41
Original file line numberDiff line numberDiff line change
@@ -720,3 +720,44 @@ def _compose_dsn(dbname, **kwargs):
720720
if v:
721721
dsn += ' %s=%s' % (k, v)
722722
return dsn, kwargs
723+
724+
725+
@asyncio.coroutine
726+
def prefetch(sq, *subqueries):
727+
"""Asynchronous version of the prefetch function from peewee.
728+
729+
Returns Query that has already cached data.
730+
"""
731+
732+
# This code is copied from peewee.prefetch and adopted to use async execute
733+
734+
if not subqueries:
735+
return sq
736+
fixed_queries = peewee.prefetch_add_subquery(sq, subqueries)
737+
738+
deps = {}
739+
rel_map = {}
740+
for prefetch_result in reversed(fixed_queries):
741+
query_model = prefetch_result.model
742+
if prefetch_result.fields:
743+
for rel_model in prefetch_result.rel_models:
744+
rel_map.setdefault(rel_model, [])
745+
rel_map[rel_model].append(prefetch_result)
746+
747+
deps[query_model] = {}
748+
id_map = deps[query_model]
749+
has_relations = bool(rel_map.get(query_model))
750+
751+
# This is hack, because peewee async execute do a copy of query and do not change state of query
752+
# comparing to what real peewee is doing when execute method is called
753+
prefetch_result.query._qr = yield from execute(prefetch_result.query)
754+
prefetch_result.query._dirty = False
755+
756+
for instance in prefetch_result.query._qr:
757+
if prefetch_result.fields:
758+
prefetch_result.store_instance(instance, id_map)
759+
if has_relations:
760+
for rel in rel_map[query_model]:
761+
rel.populate_instance(instance, deps[rel.model])
762+
763+
return prefetch_result.query

0 commit comments

Comments
 (0)