MCPcopy
hub / github.com/django/django / get_aggregation

Method get_aggregation

django/db/models/sql/query.py:457–649  ·  view source on GitHub ↗

Return the dictionary with the values of the existing aggregations.

(self, using, aggregate_exprs)

Source from the content-addressed store, hash-verified

455 return target.get_col(alias, field)
456
457 def get_aggregation(self, using, aggregate_exprs):
458 """
459 Return the dictionary with the values of the existing aggregations.
460 """
461 if not aggregate_exprs:
462 return {}
463 # Store annotation mask prior to temporarily adding aggregations for
464 # resolving purpose to facilitate their subsequent removal.
465 refs_subquery = False
466 refs_window = False
467 replacements = {}
468 annotation_select_mask = self.annotation_select_mask
469 for alias, aggregate_expr in aggregate_exprs.items():
470 self.check_alias(alias)
471 aggregate = aggregate_expr.resolve_expression(
472 self, allow_joins=True, reuse=None, summarize=True
473 )
474 if not aggregate.contains_aggregate:
475 raise TypeError("%s is not an aggregate expression" % alias)
476 # Temporarily add aggregate to annotations to allow remaining
477 # members of `aggregates` to resolve against each others.
478 self.append_annotation_mask([alias])
479 aggregate_refs = aggregate.get_refs()
480 refs_subquery |= any(
481 getattr(self.annotations[ref], "contains_subquery", False)
482 for ref in aggregate_refs
483 )
484 refs_window |= any(
485 getattr(self.annotations[ref], "contains_over_clause", True)
486 for ref in aggregate_refs
487 )
488 aggregate = aggregate.replace_expressions(replacements)
489 self.annotations[alias] = aggregate
490 replacements[Ref(alias, aggregate)] = aggregate
491 # Stash resolved aggregates now that they have been allowed to resolve
492 # against each other.
493 aggregates = {alias: self.annotations.pop(alias) for alias in aggregate_exprs}
494 self.set_annotation_mask(annotation_select_mask)
495 # Existing usage of aggregation can be determined by the presence of
496 # selected aggregates but also by filters against aliased aggregates.
497 _, having, qualify = self.where.split_having_qualify()
498 has_existing_aggregation = (
499 any(
500 getattr(annotation, "contains_aggregate", True)
501 for annotation in self.annotations.values()
502 )
503 or having
504 )
505 set_returning_annotations = {
506 alias
507 for alias, annotation in self.annotation_select.items()
508 if getattr(annotation, "set_returning", False)
509 }
510 # Decide if we need to use a subquery.
511 #
512 # Existing aggregations would cause incorrect results as
513 # get_aggregation() must produce just one result and thus must not use
514 # GROUP BY.

Callers 2

aggregateMethod · 0.80
get_countMethod · 0.80

Calls 15

check_aliasMethod · 0.95
set_annotation_maskMethod · 0.95
cloneMethod · 0.95
_gen_colsMethod · 0.95
RefClass · 0.90
AggregateQueryClass · 0.90
split_having_qualifyMethod · 0.80
clear_orderingMethod · 0.80
get_initial_aliasMethod · 0.80
add_annotationMethod · 0.80
clear_limitsMethod · 0.80

Tested by

no test coverage detected