{{{
class Foo(models.Model):
val = models.IntegerField()
}}}
with data 1, 2, 3, 4, 5. In SQL I can do (roughly)
{{{
SELECT val FROM foo WHERE COALESCE((SELECT val FROM foo WHERE val=6 LIMIT
1 OFFSET 0), 3);
}}}
to get 3, 4, and 5. Translated into Django ORM query language:
{{{
Foo.objects.filter(val__gte=Coalesce(Foo.objects.filter(val=6).values_list('val',
flat=True)[:1], 3))
}}}
I get a ProgrammingError because Django does not handle subqueries, and
passes the QuerySet object directly to the SQL backend.
The reason I don’t want to use first() instead is that I am doing some
query-joining in a loop, and repeated first() calls result in lots of
queries, dragging the database down.
--
Ticket URL: <https://code.djangoproject.com/ticket/27412>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/27412#comment:1>
Old description:
> Say I have a model
>
> {{{
> class Foo(models.Model):
> val = models.IntegerField()
> }}}
>
> with data 1, 2, 3, 4, 5. In SQL I can do (roughly)
>
> {{{
> SELECT val FROM foo WHERE COALESCE((SELECT val FROM foo WHERE val=6 LIMIT
> 1 OFFSET 0), 3);
> }}}
>
> to get 3, 4, and 5. Translated into Django ORM query language:
>
> {{{
> Foo.objects.filter(val__gte=Coalesce(Foo.objects.filter(val=6).values_list('val',
> flat=True)[:1], 3))
> }}}
>
> I get a ProgrammingError because Django does not handle subqueries, and
> passes the QuerySet object directly to the SQL backend.
>
> The reason I don’t want to use first() instead is that I am doing some
> query-joining in a loop, and repeated first() calls result in lots of
> queries, dragging the database down.
New description:
Say I have a model
{{{
class Foo(models.Model):
val = models.IntegerField()
}}}
with data 1, 2, 3, 4, 5. In SQL I can do (roughly)
{{{
SELECT val FROM foo WHERE val >= COALESCE((SELECT val FROM foo WHERE val=6
LIMIT 1 OFFSET 0), 3);
}}}
to get 3, 4, and 5. Translated into Django ORM query language:
{{{
Foo.objects.filter(val__gte=Coalesce(Foo.objects.filter(val=6).values_list('val',
flat=True)[:1], 3))
}}}
I get a ProgrammingError because Django does not handle subqueries, and
passes the QuerySet object directly to the SQL backend.
The reason I don’t want to use first() instead is that I am doing some
query-joining in a loop, and repeated first() calls result in lots of
queries, dragging the database down.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/27412#comment:2>
Comment (by onlined):
Thanks to `Subquery`, I think this ticket can be closed.
--
Ticket URL: <https://code.djangoproject.com/ticket/27412#comment:3>
* status: new => closed
* resolution: => fixed
Comment:
Confirmed support even without the `Subquery` wrapping in
[https://github.com/django/django/pull/15989 this PR].
--
Ticket URL: <https://code.djangoproject.com/ticket/27412#comment:4>
Comment (by Carlton Gibson <carlton@…>):
In [changeset:"b30c0081d4d8a31ab7dc7f72a4c7099af606ef29" b30c0081]:
{{{
#!CommitTicketReference repository=""
revision="b30c0081d4d8a31ab7dc7f72a4c7099af606ef29"
Refs #27412 -- Confirmed support for executing Coalesce(subquery).
This has been supported for subqueries wrapped in Subquery since the
expression
was introduced and for Queryset directly since Subquery resolves to
sql.Query.
Piggy-backed on the existing tests covering Coalesce handling of
EmptyResultSet
as it seemed like a proper location to combine testing.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27412#comment:5>