#36031: DecimalRangeField __contains query for a value causes DataError
-------------------------------------+-------------------------------------
     Reporter:  Trent Holliday       |                    Owner:
                                     |  amansharma612
         Type:  Bug                  |                   Status:  assigned
    Component:  contrib.postgres     |                  Version:  4.2
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Trent Holliday):

 Thanks for the patch amansharma612.

 The proposed changes have the potential for issues when querying against
 the range, if the base `DecimalField` for the range is instantiated with
 `max_digits` and `decimal_places`. When attempting to query using the
 `__contains` with a decimal that exceeds the fields precision you get the
 following error:


 {{{
 NumericValueOutOfRange: numeric field overflow
 DETAIL:  A field with precision 5, scale 2 must round to an absolute value
 less than 10^3.

   File "django/db/backends/utils.py", line 89, in _execute
     return self.cursor.execute(sql, params)

 DataError: numeric field overflow
 DETAIL:  A field with precision 5, scale 2 must round to an absolute value
 less than 10^3.
 }}}


 This is something we are doing in a custom `DecimalRangeField` so that we
 can limit the values entered and get good form validation. We currently
 have a workaround in place where we implement a custom lookup that casts
 the value while ignoring the base fields precision.

 Our current workaround which gets registered to our custom decimal range
 field:

 {{{
 class _UnboundedDecimalField(models.DecimalField):

     def db_type(self, connection):
         return "numeric"


 class UnboundedDecimalRangeContains(RangeContains):

     def get_prep_lookup(self):
         if not isinstance(self.rhs, (list, tuple, Range)):
             return Cast(self.rhs, output_field=_UnboundedDecimalField())
         return super().get_prep_lookup()
 }}}

 I recognize this is probably out of scope for Django since the Django
 provided decimal range field would not have this problem. However it does
 lead to unexpected issues when extending the provided field and
 implementing that precision. One possible way to avoid this would be to
 always have the decimal range field cast the value in the contains lookup
 as the more generic `numeric` to avoid the precision error when querying
 against the range.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36031#comment:7>
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 view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019403840da8-41c81678-be82-4340-927d-402d86eddd1f-000000%40eu-central-1.amazonses.com.

Reply via email to