qs = qs.annotate(premium_over_cheapest=models.F("price") - cheapest_query)
}}}
However this fails in the second `annotate` (`cheapest=`) since
`ResolvedOuterRef` does not descend from `BaseExpression`; so it has no
`get_group_by_cols` method:
{{{
File "/usr/local/lib/python3.8/site-
packages/django/db/models/query.py", line 1078, in annotate
clone.query.set_group_by()
File "/usr/local/lib/python3.8/site-
packages/django/db/models/sql/query.py", line 1938, in set_group_by
inspect.getcallargs(annotation.get_group_by_cols, alias=alias)
AttributeError: 'ResolvedOuterRef' object has no attribute
'get_group_by_cols'
}}}
https://github.com/django/django/blob/master/django/db/models/expressions.py
--
Ticket URL: <https://code.djangoproject.com/ticket/31251>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Comment (by OJFord):
Perhaps I was doing something silly in the first place; I've resolved my
issue by changing the subquery to first annotate (group by) all the
`type`s, whatever they are, not `OuterRef`, and then only after the `Min`
annotation `filter`ing on the `OuterRef("type")` matching the grouped by
type.
I'll leave this open for now though in case it's desired to improve the
error message in this case, or perhaps there's a more sensibly-intentioned
query that does produce the same error.
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:1>
* type: Bug => Cleanup/optimization
* version: 3.0 => master
* easy: 0 => 1
* stage: Unreviewed => Accepted
Comment:
Grouping by `OuterRef()` doesn't have much value, it's like using a
constant value, so IMO we can easily fix this with:
{{{
diff --git a/django/db/models/expressions.py
b/django/db/models/expressions.py
index 2e831b21ac..a165923784 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -562,6 +562,9 @@ class ResolvedOuterRef(F):
def relabeled_clone(self, relabels):
return self
+ def get_group_by_cols(self, alias=None):
+ return []
+
class OuterRef(F):
def resolve_expression(self, *args, **kwargs):
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:2>
* owner: nobody => Yuri Savin
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:3>
Comment (by Oliver Ford):
Why not the column that `OuterRef` is referencing? That was my intended
behaviour, though I eventually realised I was overcomplicating it and just
needed to group on the column directly, not an outer ref, and filter on
the outer ref.
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:4>
Comment (by felixxm):
Oliver, `OuterRef()` is a field from the outer query, so it will be the
same for all rows in a subquery. Is there any value in adding it to a
`GROUP BY` clause? e.g.
{{{
(SELECT MIN("price") from "subquery_table" GROUP BY "outer_table"."type")
}}}
is equivalent to
{{{
(SELECT MIN("price") from "subquery_table")
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:5>
* owner: Yuri Savin => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:6>
Comment (by Yuri Savin):
Replying to [comment:5 felixxm]:
> Oliver, `OuterRef()` is a field from the outer query, so it will be the
same for all rows in a subquery. Is there any value in adding it to a
`GROUP BY` clause? e.g.
> {{{
> (SELECT MIN("price") from "subquery_table" GROUP BY
"outer_table"."type")
> }}}
> is equivalent to
> {{{
> (SELECT MIN("price") from "subquery_table")
> }}}
I think you can close this ticket better than i'm
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:7>
* owner: (none) => Rohit Jha
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:8>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:9>
* needs_better_patch: 0 => 1
* needs_tests: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:10>
* cc: Rohit Jha (added)
* needs_tests: 1 => 0
Comment:
Tests => https://github.com/django/django/pull/12489
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:11>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"486786c4c480f5b1ae3ac1c95858b03699b9eb9c" 486786c]:
{{{
#!CommitTicketReference repository=""
revision="486786c4c480f5b1ae3ac1c95858b03699b9eb9c"
Fixed #31251 -- Disabled grouping by OuterRef() annotation.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31251#comment:13>