Skip to content

Instantly share code, notes, and snippets.

@bewt85
Last active December 19, 2015 20:09
Show Gist options
  • Save bewt85/6011735 to your computer and use it in GitHub Desktop.
Save bewt85/6011735 to your computer and use it in GitHub Desktop.
First stab at find_and_modify for MongoEngine. Can be added to mongoengine/queryset/base.py. NB As yet untested...
def andModify(self, upsert=False, sort=None, full_response=False, **update):
"""Perform an atomic update on the fields matched by the query. Returns
a document. Essentially a wrapper for PyMongo's find_and_modify; itself
a wrapper for MongoDB's findAndModify.
:param upsert: Any existing document with that "_id" is overwritten.
:param sort: a list of (key, direction) pairs specifying the sort order
for this query.
:param full_response: return the entire response object from the server.
:param update: Django-style update keyword arguments
.. versionadded:: TBC
"""
if not update and not upsert:
raise OperationError("No update parameters, must either update or remove")
queryset = self.clone()
query = queryset._query
update = transform.update(queryset._document, **update)
# If doing an atomic upsert on an inheritable class
# then ensure we add _cls to the update operation
if upsert and '_cls' in query:
if '$set' in update:
update["$set"]["_cls"] = queryset._document._class_name
else:
update["$set"] = {"_cls": queryset._document._class_name}
try:
result = queryset._collection.find_and_modify(query, update, upsert=upsert, sort=sort, full_response=full_response)
if full_response:
if not result['value'] is None:
result['value'] = self._document._from_son(result['value'])
else:
if not result is None:
result = self._document._from_son(result)
return result
except pymongo.errors.OperationFailure, err:
raise OperationError(u'findAndModify failed (%s)' % unicode(err))
@rozza
Copy link

rozza commented Jul 17, 2013

Not sure you need to do the $set on _cls as the query part will match that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment