@@ -241,11 +241,10 @@ def execute_sql(
241
241
self , result_type = MULTI , chunked_fetch = False , chunk_size = GET_ITERATOR_CHUNK_SIZE
242
242
):
243
243
self .pre_sql_setup ()
244
- columns = self .get_columns ()
245
244
try :
246
245
query = self .build_query (
247
246
# Avoid $project (columns=None) if unneeded.
248
- columns
247
+ self . columns
249
248
if self .query .annotations or not self .query .default_cols or self .query .distinct
250
249
else None
251
250
)
@@ -259,10 +258,10 @@ def execute_sql(
259
258
except StopIteration :
260
259
return None # No result
261
260
else :
262
- return self ._make_result (obj , columns )
261
+ return self ._make_result (obj , self . columns )
263
262
# result_type is MULTI
264
263
cursor .batch_size (chunk_size )
265
- result = self .cursor_iter (cursor , chunk_size , columns )
264
+ result = self .cursor_iter (cursor , chunk_size , self . columns )
266
265
if not chunked_fetch :
267
266
# If using non-chunked reads, read data into memory.
268
267
return list (result )
@@ -394,7 +393,8 @@ def build_query(self, columns=None):
394
393
query .subqueries = self .subqueries
395
394
return query
396
395
397
- def get_columns (self ):
396
+ @cached_property
397
+ def columns (self ):
398
398
"""
399
399
Return a tuple of (name, expression) with the columns and annotations
400
400
which should be loaded by the query.
@@ -472,8 +472,7 @@ def get_combinator_queries(self):
472
472
query .get_compiler (self .using , self .connection , self .elide_empty )
473
473
for query in self .query .combined_queries
474
474
]
475
- main_query_columns = self .get_columns ()
476
- main_query_fields , _ = zip (* main_query_columns , strict = True )
475
+ main_query_fields , _ = zip (* self .columns , strict = True )
477
476
for compiler_ in compilers :
478
477
try :
479
478
# If the columns list is limited, then all combined queries
@@ -490,7 +489,7 @@ def get_combinator_queries(self):
490
489
)
491
490
compiler_ .pre_sql_setup ()
492
491
compiler_ .column_indices = self .column_indices
493
- columns = compiler_ .get_columns ()
492
+ columns = compiler_ .columns
494
493
parts .append ((compiler_ .build_query (columns ), compiler_ , columns ))
495
494
except EmptyResultSet :
496
495
# Omit the empty queryset with UNION.
@@ -528,7 +527,7 @@ def get_combinator_queries(self):
528
527
combinator_pipeline = inner_pipeline
529
528
if not self .query .combinator_all :
530
529
ids = defaultdict (dict )
531
- for alias , expr in main_query_columns :
530
+ for alias , expr in self . columns :
532
531
# Unfold foreign fields.
533
532
if isinstance (expr , Col ) and expr .alias != self .collection_name :
534
533
ids [expr .alias ][expr .target .column ] = expr .as_mql (self , self .connection )
@@ -633,10 +632,9 @@ def explain_query(self):
633
632
)
634
633
# Build the query pipeline.
635
634
self .pre_sql_setup ()
636
- columns = self .get_columns ()
637
635
query = self .build_query (
638
636
# Avoid $project (columns=None) if unneeded.
639
- columns if self .query .annotations or not self .query .default_cols else None
637
+ self . columns if self .query .annotations or not self .query .default_cols else None
640
638
)
641
639
pipeline = query .get_pipeline ()
642
640
# Explain the pipeline.
@@ -796,7 +794,7 @@ def build_query(self, columns=None):
796
794
compiler .pre_sql_setup (with_col_aliases = False )
797
795
# Avoid $project (columns=None) if unneeded.
798
796
columns = (
799
- compiler .get_columns ()
797
+ compiler .columns
800
798
if self .query .annotations or not self .query .default_cols or self .query .distinct
801
799
else None
802
800
)
0 commit comments