swaroopsm
swaroopsm

Reputation: 1399

Upsert and Multi flag in pymongo

I am working on pymongo and this is my document:

{
   "_id": ObjectId("51211b57f07ddaa377000000"),
   "assignments": {
     "0": {
       "0": {
         "_id": ObjectId("5120dd7400a4453d58a0d0ec") 
      },
       "1": {
         "_id": ObjectId("5120dd8e00a4453d58a0d0ed") 
      },
       "2": {
         "_id": ObjectId("5120ddad00a4453d58a0d0ee") 
      } 
    } 
  },
   "password": "my_passwd",
   "username": "john" 
}

I would like to unset the "assignment" property of all such docs. I was able to achieve this on the mongo shell by doing:

db.users.update({}, {$unset: {"assignments": 1}}, false, true)

i.e., I passed the upsert and multi flag as the last two parameters to the update function function on users collection. However I did this with pymongo:

db.users.update({}, {"$unset": {"assignments": 1}}, False, True)

But the python interpreter threw an error as follows:

File "notes/assignment.py", line 34, in <module>
    db.users.update({}, {"$unset": {"assignments": 1}}, False, True)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 481, in update
    check_keys, self.__uuid_subtype), safe)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 852, in _send_message
    rv = self.__check_response_to_last_error(response)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 795, in __check_response_to_last_error
    raise OperationFailure(details["err"], details["code"])
pymongo.errors.OperationFailure: Modifiers and non-modifiers cannot be mixed

Where am I going wrong?

Upvotes: 12

Views: 11798

Answers (1)

James Brewer
James Brewer

Reputation: 1755

The problem is that the two flags you are passing in aren't upsert and multi. Based on the documentation of PyMongo's Collection.update (found here), it looks like you might be passing in values for the upsert and manipulate options, although I am not certain.

All you have to do to solve this is use one of Python's most awesome features: named arguments. By specifying which options you are passing to update, you add clarity to your code in addition to making sure accidents like this don't happen.

In this case, we want to pass the options upsert=False and multi=True.

db.users.update({}, { "$unset": { "assignments": 1 } }, upsert=False, multi=True)

Upvotes: 28

Related Questions