mongoengine icon indicating copy to clipboard operation
mongoengine copied to clipboard

DecimalField inequality search is unusable

Open tko opened this issue 14 years ago • 3 comments

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

tko avatar Oct 25 '11 16:10 tko

because decimal fields is archived in string format

wpjunior avatar Oct 26 '11 11:10 wpjunior

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.

tko avatar Oct 27 '11 19:10 tko

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.

hassek avatar Jan 12 '12 03:01 hassek