@@ -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
@@ -485,8 +485,7 @@ def get_combinator_queries(self):
485
485
query .get_compiler (self .using , self .connection , self .elide_empty )
486
486
for query in self .query .combined_queries
487
487
]
488
- main_query_columns = self .get_columns ()
489
- main_query_fields , _ = zip (* main_query_columns , strict = True )
488
+ main_query_fields , _ = zip (* self .columns , strict = True )
490
489
for compiler_ in compilers :
491
490
try :
492
491
# If the columns list is limited, then all combined queries
@@ -507,7 +506,7 @@ def get_combinator_queries(self):
507
506
)
508
507
compiler_ .pre_sql_setup ()
509
508
compiler_ .column_indices = self .column_indices
510
- columns = compiler_ .get_columns ()
509
+ columns = compiler_ .columns
511
510
parts .append ((compiler_ .build_query (columns ), compiler_ , columns ))
512
511
except EmptyResultSet :
513
512
# Omit the empty queryset with UNION.
@@ -545,7 +544,7 @@ def get_combinator_queries(self):
545
544
combinator_pipeline = inner_pipeline
546
545
if not self .query .combinator_all :
547
546
ids = defaultdict (dict )
548
- for alias , expr in main_query_columns :
547
+ for alias , expr in self . columns :
549
548
# Unfold foreign fields.
550
549
if isinstance (expr , Col ) and expr .alias != self .collection_name :
551
550
ids [expr .alias ][expr .target .column ] = expr .as_mql (self , self .connection )
@@ -650,10 +649,9 @@ def explain_query(self):
650
649
)
651
650
# Build the query pipeline.
652
651
self .pre_sql_setup ()
653
- columns = self .get_columns ()
654
652
query = self .build_query (
655
653
# Avoid $project (columns=None) if unneeded.
656
- columns if self .query .annotations or not self .query .default_cols else None
654
+ self . columns if self .query .annotations or not self .query .default_cols else None
657
655
)
658
656
pipeline = query .get_pipeline ()
659
657
# Explain the pipeline.
@@ -807,7 +805,7 @@ def build_query(self, columns=None):
807
805
compiler .pre_sql_setup (with_col_aliases = False )
808
806
# Avoid $project (columns=None) if unneeded.
809
807
columns = (
810
- compiler .get_columns ()
808
+ compiler .columns
811
809
if self .query .annotations or not self .query .default_cols or self .query .distinct
812
810
else None
813
811
)
0 commit comments