#27719: Add queryset.alias() to mimic .annotate() for aggregations without
loading
data
-------------------------------------+-------------------------------------
Reporter: Marc Tamlyn | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Marc Tamlyn):
I take your point about the select list, most of those APIs (e.g. values,
distinct) do indeed require the field to be selected making alias slightly
redundant.
For me it's very explicitly not a hack, and the fact we can use annotate
is the hack. But that's bikeshedding.
More practically, consider this code:
{{{
query = SearchQuery('some term')
return qs.alias(
main_vector=SearchVector('title', 'body'),
secondary_vector=SearchVector('parent__title', 'parent__body'),
).alias(
vector=F('main_vector') + F('secondard_vector'),
).alias(
rank=Case(
When(vector__search=query, then=SearchRank('vector', query)),
When(secondary_vector__search=query,
then=SearchRank('secondary_vector', query)),
# other cases here
)
).order_by('-rank')
}}}
(I'm aware this example is contrived, but I have some pretty complex
annotations for reporting, and they're even more fun with `SubQuery`... In
most of these cases it doesn't matter that this field is in the
select_list, although it doesn't need to be.
Here I've actually used the "alias approach" and the "variable approach" -
one for vectors and one for queries.
The alias approach has allowed me to:
- Incrementally build up expressions in the query
- Name values and potentially reuse them at a later time in the query
creation phase - perhaps I have some other function which takes the
returned queryset from this method and counts the records where the rank
is > 0.7 to give an indication of strong matching results, then without
the naming from annotate or alias I'd have to access or recreate the
component expressions. Rank is an int, so again it doesn't really matter
to have it queryable.
I think #25367 is an important piece of work, and it would help solve the
performance problem by allowing unselected values. I think though that
there is a merit in being able to create a "virtual field" using an
expression, and use it in subsequent querysets. This would be an easier
solution to this particular performance issue, and it also gives the user
explicit API control over the select list where needed, rather than
implicitly by how you used your expression. It's not an either/or
scenario.
--
Ticket URL: <https://code.djangoproject.com/ticket/27719#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/066.614ebf34b122a6bfe99d072b4d56929f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.