#29338 closed Bug (fixed)
Can't use OuterRef in union Subquery
Reported by: | Matthew Pava | Owned by: | Mariusz Felisiak |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Jeff, Can Sarıgöl, InvalidInterrupt | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When you make a QuerySet using the union
method or the |
operator, the QuerySet passed into the union
method cannot reference OuterRef
even when wrapped with Subquery
.
For example:
cls = Document.objects.filter( checklist__isnull=False, part=OuterRef('id') ).values('checklist__customer', 'created') ots = Document.objects.filter( ownershiptransfer__isnull=False, part=OuterRef('id') ).values('ownershiptransfer__ship_target__contact', 'created') return self.annotate( owner=Subquery(cls.union(ots).values('owner')[:1]) )
Returns this error:
ValueError This queryset contains a reference to an outer query and may only be used in a subquery.
I get the same error with this statement:
return self.annotate( owner=Subquery((cls | ots).values('owner')[:1]) )
(As an aside, I also get an error when I try to apply an order_by
clause.)
Change History (19)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Yes, it is possible to generate SQL for this query. I tried it myself. ...I suppose "sensible" is a subjective term.
I just tried using an __in
lookup, but that was getting to be a struggle.
Maybe Subquery
wasn't originally intended to be used with unions
, but I think it would be a good feature to have, especially in the discussion of CTEs (common table expressions).
comment:3 by , 7 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:4 by , 6 years ago
Cc: | added |
---|
comment:5 by , 6 years ago
Cc: | added |
---|---|
Has patch: | set |
hi, I thought that we can use union queries in subqueries by replacing the alias from origin query to union queries. I've pushed a commit. if this approach is ok, I can add other tests and go further? PR
comment:6 by , 6 years ago
cls = Document.objects.filter( checklist__isnull=False, part=OuterRef('id') ).values('checklist__customer', 'created') ots = Document.objects.filter( ownershiptransfer__isnull=False, part=OuterRef('id') ).values('ownershiptransfer__ship_target__contact', 'created') return self.annotate( owner=Subquery(cls.union(ots).values('owner')[:1]) )
I change the example like this:
cls = Document.objects.filter( checklist__isnull=False, ).values('checklist__customer', 'created') ots = Document.objects.filter( ownershiptransfer__isnull=False, ).values('ownershiptransfer__ship_target__contact', 'created') return self.annotate( owner=Subquery(cls.union(ots).filter(part=OuterRef('id')).values('owner')[:1]) )
comment:7 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:9 by , 6 years ago
Version: | 2.0 → master |
---|
comment:10 by , 6 years ago
Owner: | removed |
---|
comment:11 by , 6 years ago
Patch needs improvement: | set |
---|
comment:12 by , 6 years ago
Status: | assigned → new |
---|
comment:14 by , 5 years ago
Owner: | set to |
---|---|
Patch needs improvement: | unset |
Status: | new → assigned |
comment:15 by , 5 years ago
Patch needs improvement: | set |
---|
comment:16 by , 4 years ago
Cc: | added |
---|
comment:17 by , 3 years ago
Patch needs improvement: | unset |
---|
Are you sure that generating some sensible SQL for this queryset is possible?