mongoengine
mongoengine copied to clipboard
DecimalField inequality search is unusable
from decimal import Decimal
class QuerySetDecimalTest(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
class Person(Document):
money = DecimalField()
Person.drop_collection()
Person(money=6).save()
Person(money=8).save()
Person(money=10).save()
self.Person = Person
def test_as_decimal(self):
self.assertEqual(2, len(self.Person.objects(money__gt=Decimal("7"))))
def test_as_int(self):
self.assertEqual(2, len(self.Person.objects(money__gt=7)))
def test_as_string(self):
self.assertEqual(2, len(self.Person.objects(money__gt="7")))
None of the searches produce expected results, and one of them even throws an exception.
InvalidDocument: Cannot encode object: Decimal('7')
self.assertEqual(2, len(self.Person.objects(money__gt=7)))
AssertionError: 2 != 0
self.assertEqual(2, len(self.Person.objects(money__gt="7")))
AssertionError: 2 != 1
because decimal fields is archived in string format
FWIW I ended up working around this by implementing a custom field for fixed precision decimals. By storing the value as scaled integer (decimal * 100, good enough for many monetary uses) we still have support for the numerical inequality search.
I can post the code or prepare a pull request if there's interest.
This Decimal problem leads to some map_reduce functions (like average, sum, etc) not to function, it appends instead of doing the summation. It would be great to handle the issue in a better way like tko says with scaled integers.