Opened 3 years ago
Last modified 3 years ago
#33033 closed Bug
NaN can be stored in DecimalField but cannot be retrieved — at Version 1
Reported by: | dennisvang | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Carlton Gibson | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Description
If, for whatever reason, a NaN
value (either float('nan')
, math.nan
, or numpy.nan
) is stored in a DecimalField
using sqlite3
, the object cannot be retrieved from the database.
Attempts to do so will raise TypeError: argument must be int or float
This issue also breaks e.g. the admin changelist view.
Steps to reproduce
- Create a brand new project using python 3.8.10 and django 3.2.6 with the default
sqlite3
backend (optionally with numpy 1.21.2).
- Create a model with a
DecimalField
:
class MyModel(models.Model): value = models.DecimalField(max_digits=10, decimal_places=5)
- Programmatically create a model instance with
value=float('nan')
(ormath.nan
, ornumpy.nan
), then try to retrieve the object from the database (or refresh from database).
obj = MyModel.objects.create(value=float('nan')) # the following raises a "TypeError: argument must be int or float" obj.refresh_from_db()
- Visiting the admin changelist view for the model will also raise the error.
Traceback:
Internal Server Error: /nanbug/mymodel/1/change/ Traceback (most recent call last): File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 232, in inner return view(request, *args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1660, in change_view return self.changeform_view(request, object_id, form_url, extra_context) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1540, in changeform_view return self._changeform_view(request, object_id, form_url, extra_context) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1561, in _changeform_view obj = self.get_object(request, unquote(object_id), to_field) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/contrib/admin/options.py", line 763, in get_object return queryset.get(**{field.name: object_id}) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/models/query.py", line 431, in get num = len(clone) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/models/query.py", line 262, in __len__ self._fetch_all() File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/models/query.py", line 1324, in _fetch_all self._result_cache = list(self._iterable_class(self)) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/models/query.py", line 68, in __iter__ for row in compiler.results_iter(results): File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1122, in apply_converters value = converter(value, expression, connection) File "/home/.../.local/share/virtualenvs/howto-GW7qAAiJ/lib/python3.8/site-packages/django/db/backends/sqlite3/operations.py", line 313, in converter return create_decimal(value).quantize(quantize_value, context=expression.output_field.context) TypeError: argument must be int or float
Change History (1)
comment:1 by , 3 years ago
Description: | modified (diff) |
---|---|
Summary: | numpy.nan can be stored in DecimalField but cannot be retrieved → NaN can be stored in DecimalField but cannot be retrieved |
Note:
See TracTickets
for help on using tickets.