项目场景:
例如:项目场景:mongoDB的文档更新,拿到一条新数据,数据证号一样,但和历史数据时间不一样,因此要更新
问题描述
mongoDB的更新方法update_one报错
new_collection.update_one(mydoc, {"$set": r})
数据库表链接.update_one(唯一查询条件或者find_one的对象(历史数据库数据), {"$set": 新文档数据})
完整报错
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\twisted\internet\defer.py", line 891, in _runCallbacks
current.result = callback( # type: ignore[misc]
File "C:\ProgramData\Anaconda3\lib\site-packages\scrapy\utils\defer.py", line 162, in f
return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
File "C:\Users\Administrator\Desktop\rhinoweCode\XnSpider\XnSpider\pipelines.py", line 125, in process_item
add_wuzheng(collectionName, items)
File "C:\Users\Administrator\Desktop\rhinoweCode\XnSpider\XnSpider\utils\Handle.py", line 1067, in add_wuzheng
add_ys(items, '', '', [], [], [], [], [])
File "C:\Users\Administrator\Desktop\rhinoweCode\XnSpider\XnSpider\utils\Handle.py", line 1039, in add_ys
new_collection.update_one(mydoc, {"$set": r})#.update(r)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\collection.py", line 1028, in update_one
self._update_retryable(
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\collection.py", line 877, in _update_retryable
return self.__database.client._retryable_write(
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\mongo_client.py", line 1552, in _retryable_write
return self._retry_with_session(retryable, func, s, None)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\mongo_client.py", line 1438, in _retry_with_session
return self._retry_internal(retryable, func, session, bulk)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\mongo_client.py", line 1470, in _retry_internal
return func(session, sock_info, retryable)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\collection.py", line 869, in _update
return self._update(
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\collection.py", line 846, in _update
_check_write_command_response(result)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\helpers.py", line 229, in _check_write_command_response
_raise_last_write_error(write_errors)
File "C:\ProgramData\Anaconda3\lib\site-packages\pymongo\helpers.py", line 211, in _raise_last_write_error
raise WriteError(error.get("errmsg"), error.get("code"), error)
pymongo.errors.WriteError: Performing an update on the path '_id' would modify the immutable field '_id', full error: {'index': 0, 'code': 66, 'errmsg': "Performing an update on the path '_id' would modify the immutable field '_id'"}
2023-02-07 15:47:05
MongoDB 在路径“_id”上执行更新将修改不可变字段“_id”
我的数据库建立了索引,因为两条数据只有时间不同,索引字段完全相同,插入的时候因为时间不同,会形成不同的自增id,导致这个数据插入的id重复
原因分析:
- 数据库某个字段被设置成了unique,在插入的时候这个字段出现了重复;
- update_one 使用时所插入的文档列表中存在指向同一个对象的多个元素,这个本质上跟第一种情况是一样的,因为每个元素被插入之后都会被添加了一个_id字段,而相同的指向相当于同一个_id被插入了两次,就会冲突出现上述的问题。
解决方案:把历史数据的_id加入到对应新数据,避免mongoDB自动生成新_id才能在原始数据完成更新,如果没有出现报错可能因为旧版本mongoDB不报这个错误
# 新文档数据_id设置为mydoc历史数据
r["_id"]=mydoc["_id"]
new_collection.update_one(mydoc, {"$set": r})