Skip to content

Instantly share code, notes, and snippets.

@grubberr
Created November 15, 2017 12:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grubberr/cc2edf5928395bbd305b97431b5be4f4 to your computer and use it in GitHub Desktop.
Save grubberr/cc2edf5928395bbd305b97431b5be4f4 to your computer and use it in GitHub Desktop.
mongoengine atomic get_or_create using findAndModify
#!/usr/bin/env python3
from mongoengine import Document, IntField, StringField, connect
connect('test')
class ChatUser(Document):
_access = IntField() # internal access counter
chat_id = IntField(required=True, unique=True)
platform = StringField(required=True, choices=('telegram', 'facebook'), default='telegram')
name = StringField(required=True)
state = StringField()
@classmethod
def get_or_create(cls, query, new=None):
setOnInsert = cls().to_mongo().to_dict()
if new:
setOnInsert.update(new)
update = {'$inc': {'_access': 1}}
if setOnInsert:
update['$setOnInsert'] = setOnInsert
res = cls._get_collection().find_one_and_update(
query, update, return_document=True, upsert=True)
if res['_access'] == 1:
print("create")
else:
print("get")
res['id'] = res.pop('_id')
return cls(**res)
ChatUser.get_or_create(query={'chat_id': 1234}, new={'name': 'user'})
ChatUser.get_or_create(query={'chat_id': 1234}, new={'name': 'user'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment