@@ -241,11 +241,10 @@ def execute_sql(
241241 self , result_type = MULTI , chunked_fetch = False , chunk_size = GET_ITERATOR_CHUNK_SIZE
242242 ):
243243 self .pre_sql_setup ()
244- columns = self .get_columns ()
245244 try :
246245 query = self .build_query (
247246 # Avoid $project (columns=None) if unneeded.
248- columns
247+ self . columns
249248 if self .query .annotations or not self .query .default_cols or self .query .distinct
250249 else None
251250 )
@@ -259,10 +258,10 @@ def execute_sql(
259258 except StopIteration :
260259 return None # No result
261260 else :
262- return self ._make_result (obj , columns )
261+ return self ._make_result (obj , self . columns )
263262 # result_type is MULTI
264263 cursor .batch_size (chunk_size )
265- result = self .cursor_iter (cursor , chunk_size , columns )
264+ result = self .cursor_iter (cursor , chunk_size , self . columns )
266265 if not chunked_fetch :
267266 # If using non-chunked reads, read data into memory.
268267 return list (result )
@@ -394,7 +393,8 @@ def build_query(self, columns=None):
394393 query .subqueries = self .subqueries
395394 return query
396395
397- def get_columns (self ):
396+ @cached_property
397+ def columns (self ):
398398 """
399399 Return a tuple of (name, expression) with the columns and annotations
400400 which should be loaded by the query.
@@ -472,8 +472,7 @@ def get_combinator_queries(self):
472472 query .get_compiler (self .using , self .connection , self .elide_empty )
473473 for query in self .query .combined_queries
474474 ]
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 )
477476 for compiler_ in compilers :
478477 try :
479478 # If the columns list is limited, then all combined queries
@@ -490,7 +489,7 @@ def get_combinator_queries(self):
490489 )
491490 compiler_ .pre_sql_setup ()
492491 compiler_ .column_indices = self .column_indices
493- columns = compiler_ .get_columns ()
492+ columns = compiler_ .columns
494493 parts .append ((compiler_ .build_query (columns ), compiler_ , columns ))
495494 except EmptyResultSet :
496495 # Omit the empty queryset with UNION.
@@ -528,7 +527,7 @@ def get_combinator_queries(self):
528527 combinator_pipeline = inner_pipeline
529528 if not self .query .combinator_all :
530529 ids = defaultdict (dict )
531- for alias , expr in main_query_columns :
530+ for alias , expr in self . columns :
532531 # Unfold foreign fields.
533532 if isinstance (expr , Col ) and expr .alias != self .collection_name :
534533 ids [expr .alias ][expr .target .column ] = expr .as_mql (self , self .connection )
@@ -633,10 +632,9 @@ def explain_query(self):
633632 )
634633 # Build the query pipeline.
635634 self .pre_sql_setup ()
636- columns = self .get_columns ()
637635 query = self .build_query (
638636 # 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
640638 )
641639 pipeline = query .get_pipeline ()
642640 # Explain the pipeline.
@@ -796,7 +794,7 @@ def build_query(self, columns=None):
796794 compiler .pre_sql_setup (with_col_aliases = False )
797795 # Avoid $project (columns=None) if unneeded.
798796 columns = (
799- compiler .get_columns ()
797+ compiler .columns
800798 if self .query .annotations or not self .query .default_cols or self .query .distinct
801799 else None
802800 )
0 commit comments