Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do "insert if not exist else update" with mongoengine?

I'm working with mongoengine in Django,
this is my document defination:

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

I want to do this:
given a user_id and a point:
if there is no document that have this user_id, create one with the user_id and point and save it;
else update the document with user_id with point.
Can I do this in one statement with mongoengine?

like image 493
wong2 Avatar asked Dec 09 '11 15:12

wong2


4 Answers

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.

like image 72
Nicolas Cortot Avatar answered Oct 20 '22 20:10

Nicolas Cortot


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.

like image 35
arthur.sw Avatar answered Oct 20 '22 21:10

arthur.sw


this is what I came up with:

location = Location.objects.get_or_create(user_id=user_id)[0]  
location.point = point  
location.save()
like image 34
wong2 Avatar answered Oct 20 '22 21:10

wong2


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
like image 23
esteininger Avatar answered Oct 20 '22 20:10

esteininger