#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 , 8 years ago
comment:2 by , 8 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 , 8 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:4 by , 7 years ago
| Cc: | added |
|---|
comment:5 by , 7 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 , 7 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 , 7 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:9 by , 7 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 , 6 years ago
| Owner: | set to |
|---|---|
| Patch needs improvement: | unset |
| Status: | new → assigned |
comment:15 by , 6 years ago
| Patch needs improvement: | set |
|---|
comment:16 by , 5 years ago
| Cc: | added |
|---|
comment:17 by , 4 years ago
| Patch needs improvement: | unset |
|---|
Are you sure that generating some sensible SQL for this queryset is possible?