I think the approach you have taken is correct in general. I would encourage to check
if you can somewhat easily incorporate the conditional aggregate support (#11305)
into the ExpressionNode based aggreagates. It does not belong into the same
patch, but is a good sanity check if the approach taken is extensible.
[Following is a bit off-topic]
I wonder if the ExpressionNode itself should be refactored into a public API. This way
you could easily write your own SQL snippets injectable into the query. This could be
custom aggregates, or this could be just NULLS LAST order by clauses.
The reason I bring this up is that in the long run, adding more and more special case
support to the ORM (conditional aggregates, different SQL functions) doesn't seem to be
the right way forward. Once you get expression composition in, you only have 90% of
SQL constructs left...
Spend the time in building support for user writable SQL snippets, so that they can
use just the SQL they want. In my opinion NULLS LAST/FIRST support is a great
example: it is common enough that users need it from time to time, but it is not common
enough to spend the time to support this special case. Why not just:
qs.order_by(SQL('%s NULLS LAST', F('pub_date'))
and you now got support for _any_ order by clause the user wishes to use. Replaces
extra(), but in a cleaner way. The above could support relabel_aliases(). Or you could
write it just as qs.order_by(SQL('pub_date NULLS LAST')) if you don't care for relabel
aliases support.
For the F-expression support in aggregates this would mean you get actually not just
F expression support in aggregates, but any SQL snippet can be injected into the
aggregates, for example Sum(SQL('case when person.age > friend.age then 1 else 0 end'))
- Anssi
________________________________________
From: django-d...@googlegroups.com [django-d...@googlegroups.com] On Behalf Of Nate Bragg [jonatha...@alum.rpi.edu]
Sent: Wednesday, March 21, 2012 01:27
To: django-d...@googlegroups.com
Subject: Complex aggregate and expression composition.
Hello all,
https://github.com/NateBragg/django/tree/14030
-- Nate Bragg
--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-d...@googlegroups.com.
To unsubscribe from this group, send email to django-develop...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
I took a quick look at your patch. I don't have more time now, so just some quick comments:
[...]
I think the approach you have taken is correct in general. I would encourage to check
if you can somewhat easily incorporate the conditional aggregate support (#11305)
into the ExpressionNode based aggreagates. It does not belong into the same
patch, but is a good sanity check if the approach taken is extensible.
- I am a bit scared of the type coercions. The reason is that this could prove to be
hopelessly complex to get right in every case. However, I do not have concrete
examples where this is in fact a problem. The default should probably not be an exception,
but just returning what the database happens to give you back.