#27473: Use/enable db.models.functions.Extract with/for DurationFields
-------------------------------------+-------------------------------------
Reporter: Daniel | Owner: nobody
Hahler |
Type: New | Status: new
feature |
Component: Database | Version: 1.10
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I am trying to use `Extract` on a duration field, but this results in
`ValueError: Extract input expression must be DateField, DateTimeField, or
TimeField.`:
{{{
qs = qs.annotate(
speed=Sum(
F('distance_in_meters') * Value(3.6) /
Extract(F('duration_in_seconds'), 'epoch'),
output_field=FloatField()),
)
}}}
The following patch however makes it work on PostgreSQL, so it should be
considered to be enabled there - in case other DB backends do not support
it:
{{{
diff --git i/django/db/models/functions/datetime.py
w/django/db/models/functions/datetime.py
index 2980460..3266ef6 100644
--- i/django/db/models/functions/datetime.py
+++ w/django/db/models/functions/datetime.py
@@ -5,6 +5,7 @@
from django.conf import settings
from django.db.models import (
DateField, DateTimeField, IntegerField, TimeField, Transform,
+ DurationField,
)
from django.db.models.lookups import (
YearExact, YearGt, YearGte, YearLt, YearLte,
@@ -52,6 +53,8 @@ def as_sql(self, compiler, connection):
sql = connection.ops.date_extract_sql(self.lookup_name, sql)
elif isinstance(lhs_output_field, TimeField):
sql = connection.ops.time_extract_sql(self.lookup_name, sql)
+ elif isinstance(lhs_output_field, DurationField):
+ sql = connection.ops.date_extract_sql(self.lookup_name, sql)
else:
# resolve_expression has already validated the output_field
so this
# assert should never be hit.
@@ -61,7 +64,7 @@ def as_sql(self, compiler, connection):
def resolve_expression(self, query=None, allow_joins=True,
reuse=None, summarize=False, for_save=False):
copy = super(Extract, self).resolve_expression(query,
allow_joins, reuse, summarize, for_save)
field = copy.lhs.output_field
- if not isinstance(field, (DateField, DateTimeField, TimeField)):
+ if not isinstance(field, (DateField, DateTimeField, TimeField,
DurationField)):
raise ValueError('Extract input expression must be DateField,
DateTimeField, or TimeField.')
# Passing dates to functions expecting datetimes is most likely a
mistake.
if type(field) == DateField and copy.lookup_name in ('hour',
'minute', 'second'):
}}}
Am I missing something?
What needs to be done to get it enabled for DurationFields?
--
Ticket URL: <https://code.djangoproject.com/ticket/27473>
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/050.1486dae47d5974264682a7598181b24c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.