Python中Pymongo的update方法常见错误及解决方法

首先是代码:

DB.test.update(query={'host': ip, 'port': port}, update={$set: {'http': 'test'}})

这个代码会报这样的错误:

TypeError: 'update() takes at least 3 arguments (1 given)'

在这个之前我使用了最最简单的:

DB.test.update({'host': ip, 'port': port}, {"$set": {'http': 'test'}})

报的错误:

TypeError: "unhashable type: 'dict'"

我一脸的蒙蔽阿。什么情况。 这个是问题是在这个主题的一个简单解决方案。这情况怎么解决?


Python中Pymongo的update方法常见错误及解决方法

3 回复

帖子回复:

Pymongo的update方法(特别是旧版update_one/update_many出现前的写法)确实容易踩坑。最常见的问题集中在操作符使用更新目标上。下面直接上代码说明:

1. 错误:直接赋值代替操作符

# 错误示例:这会把整个文档替换成{"name": "new_name"},而不是更新字段
collection.update({"_id": 1}, {"name": "new_name"})

# 正确:使用$set操作符
collection.update_one({"_id": 1}, {"$set": {"name": "new_name"}})

2. 错误:混淆更新条件与更新内容

# 错误:第二个参数误用了查询语法
collection.update({"_id": 1}, {"name": "old_name"})  # 这会把匹配到的文档改成{"name": "old_name"}

# 正确:明确区分查询条件和更新操作
collection.update_many({"status": "old"}, {"$set": {"status": "new"}})

3. 错误:upsert参数使用不当

# 错误:upsert=True时,如果查询条件不匹配,会插入一个包含查询条件的文档
collection.update_one({"user": "john"}, {"$inc": {"count": 1}}, upsert=True)
# 如果不存在user=john的文档,会插入{"user": "john", "count": 1},而不是{"count": 1}

# 正确:在更新文档中明确所有字段
collection.update_one(
    {"user": "john"},
    {"$setOnInsert": {"user": "john"}, "$inc": {"count": 1}},
    upsert=True
)

4. 错误:批量更新时误用multi参数(旧API)

# 旧版写法(不推荐):
collection.update({"status": "pending"}, {"$set": {"status": "processed"}}, multi=True)

# 新版应该直接用update_many:
collection.update_many({"status": "pending"}, {"$set": {"status": "processed"}})

关键建议:

  • 始终使用update_one()update_many()替代旧的update()方法
  • 更新字段时一定要用$set$inc等操作符,除非确实要替换整个文档
  • 使用upsert=True时,用$setOnInsert处理插入时的初始值

一句话总结:明确区分查询条件和更新操作,该用操作符时别手懒。


第一行代码你的$set 没有加引号, Python 懵逼
另外 update 已经被 deprecated ,推荐使用 update_one() 或者 update_many()

回到顶部