Search code examples
pythonpymongomongoengineatomic

How to atomically remove a key from a dictionary in Mongoengine/Pymongo?


So it's mainly a Mongoengine question but looking at the error the issue seems to be in the underlying pymongo layer so I figure I should mention both. Basically i have a model like this Edit: Updated to show more of the class definitions

class MyModel(Document):
    dictField = DictField()

class PermHolder(Document):
    meta = {'allow_inheritance': True}
    ....

class ValClass(PermHolder):
    ....

and in my code I'm trying to manipulate that dictionary using atomic updates (I had weird race condition problems before when trying normal methods and saving). Also, because the key is a variable I had to use kwargs as my argument into the update function

modelObject = MyModel.objects.get(id=blah)
valVar = ValClass.objects.get(id=blah)

# This works at adding the binding modelObject[keyVar] = valVar
modelObject.update(**{'set__dictField__' + keyVar: valVar })
...
# Trying to remove the binding later on
modelObject.update(**{'unset__dictField__' + keyVar: valVar })

So the second call when I try to remove gives me the error

 Cannot encode object: <ValClass: 51e94b55bc616310e5e4f3fb>

Which is strange because the set command worked. is there another way to remove this and I'm using the incorrect syntax?


Solution

  • If valVar is an instance of a class and is stored by objectId - try:

    modelObject.update(**{'unset__dictField__' + keyVar: valVar.id })