mongoengine icon indicating copy to clipboard operation
mongoengine copied to clipboard

dec atomic operation on Float/Decimal/Int Field is broken

Open ajdas-code opened this issue 5 years ago • 5 comments

It seems that the mongoengine is broken for atomic dec operation a FloatField or DecimalField.

Here is what i am trying -

class Account (DynamicDocument): 
    user = ReferenceField(User,passthrough=True,reverse_delete_rule=True,required=True,unique=True)
    amount = FloatField(min_value=0,required=True)

Now I am trying to perform a atomic "dec" operation. The "amnt" value is passed as 10

Account.objects(user=usr).update(dec__amount=amnt)

However, I am getting error - mongoengine.error.ValidationError: Float value is too small. Any help is greatly appreciated. Thanks

ajdas-code avatar May 30 '20 16:05 ajdas-code

Good catch, its taking the min_value into account to validate the value but it shouldn't in case of inc/dec

As a workaround, you can use the __raw__ update, it will bypass the mongoengine validation: Account.objects(user=usr).update(__raw__={"$inc": {"amount": -amnt}})

bagerard avatar Jun 20 '20 18:06 bagerard

This still seems to be broken. Just stumbled on the same error myself for Int field.

Can this be resolved? Thanks

shalabhsingh avatar Oct 15 '20 22:10 shalabhsingh

Dear all. I'm also experiencing this issue. The thread seems to have been closed but the bug persists in the latest version v0.22.1. I was wondering if there is any plan on a fix? Thanks in advance.

shuheng-liu avatar Jan 14 '21 08:01 shuheng-liu

The issue is that the validation in IntField is incorrect: when validating, the comparison done is the following:

if self.min_value is not None and value < self.min_value:
    self.error("Integer value is too small")

However, here value is the argument of dec, which means that for a min_value=0, this will fail for any decrement. I believe the problem lies in the fact that this is the wrong validation function to use in this context.

The same issue lies with the validation for the max_value: if someone were to say that max_value=0 for a field containing only non-positive integers, then any inc command will fail.

I do not believe that the validation should be skipped for either inc or dec, but the validation should be done by taking into account the current value of the field, as well as the increment/decrement, although I'm not sure if this is feasible in the current framework (I'm fairly new to mongoengine, so perhaps I'm wrong on this).

kientuong114 avatar Feb 18 '21 15:02 kientuong114

@bagerard your workaround is working well but when can we expect some fix for this? This was raised more than a couple of years back.

sriharan16 avatar Nov 17 '22 06:11 sriharan16