pymongo中的Upsert和多选项标志

12 投票
1 回答
11709 浏览
提问于 2025-04-17 16:11

我正在使用pymongo,这是我的文档:

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

我想要删除所有这些文档中的“assignment”属性。我在mongo命令行中可以这样做到:

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

也就是说,我在更新用户集合时,把upsert和multi这两个参数作为最后两个参数传给了更新函数。不过我在pymongo中这样做:

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

但是Python解释器报了一个错误,如下所示:

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

我哪里出错了?

1 个回答

28

问题在于你传入的两个标志不是 upsertmulti。根据 PyMongo 的 Collection.update 文档(可以在 这里 找到),看起来你可能传入了 upsertmanipulate 选项的值,不过我不太确定。

要解决这个问题,你只需要使用 Python 最棒的功能之一:命名参数。通过明确指定你传给 update 的选项,你不仅让代码更清晰,还能避免像这样的意外发生。

在这个例子中,我们想要传入的选项是 upsert=Falsemulti=True

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

撰写回答