@@ -720,3 +720,44 @@ def _compose_dsn(dbname, **kwargs):
720
720
if v :
721
721
dsn += ' %s=%s' % (k , v )
722
722
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