[Django]-How to do "insert if not exist else update" with mongoengine?

47👍

Note that get_or_create is now scheduled to be deprecated, because with no transaction support in MongoDB it cannot ensure atomicity.

The preferred way is update with upsert:

Location.objects(user_id=user_id).update_one(set__point=point, upsert=True)

More on upserts on the MongoDB documentation.

8👍

There is a new way to do it since version 0.9 (explained here):

location = Location.objects(user_id=user_id).modify(upsert=True, new=True, set__point=point)

It returns the created or updated object.

5👍

this is what I came up with:

location = Location.objects.get_or_create(user_id=user_id)[0]  
location.point = point  
location.save()
👤wong2

1👍

Or you can add a method to your class object via:

class Location(mongoengine.Document):  
    user_id = mongoengine.IntField(required=True)  
    point = mongoengine.GeoPointField(required=True)

    def register(self):
        # if doesnt exist, create user id and point field
        if not Location.objects(user_id=self.user_id):
            self.user_id = self.user_id
            self.point = self.point
            self.save()
            return True
        # does exist, do nothing
        else:
            return False

0👍

My solution to update of not exist was this:

    def upsert(self, data: dict, query: dict):
        try:
            sets = {}
            for key in data.keys():
                sets[f"set__{key}"] = data[key]
            response = self.model.objects(**query).update_one(upsert=True, **sets)
            return response
        except Exception as ex:
            # Logger(str(ex)).log_error()
            return False

or if you want, you can use the method update.

Leave a comment