CosmosDB Python SDK:replace_item/upsert_item意外删除记录问题
问题原因与解决方案
核心问题
你遇到的不是文档被删除,而是Cosmos DB的替换/插入操作会完全覆盖原文档:当你传入仅包含id和property的body时,原文档中所有未被包含的字段都会被清空,最终文档只剩这两个字段,看起来像是被删除了。
代码问题分析
你的查询只获取了文档的id,之后构造的record对象仅包含id和新增的property。执行replace_item或upsert_item时,Cosmos DB会用这个对象完全替换原文档,原文档里的something等其他字段都会被移除。
另外,用item=record触发KeyError的原因是:SDK需要从item对象中读取分区键字段(比如你的容器分区键是/something),但你的record里没有这个字段,所以抛出KeyError。
解决方案
方案1:用Patch操作(推荐,省RU)
使用Cosmos DB的patch_item方法做增量更新,不需要拉取全量文档,只更新指定字段,保留原文档其他内容:
dbList = list(dbContainer.query_items( query="SELECT c.id FROM c WHERE c.something = @something", parameters=[ dict(name='@something', value=whatever) ], enable_cross_partition_query=True )) if dbList: record_id = dbList[0]['id'] try: # 仅更新指定属性,不影响其他字段 container.patch_item( item=record_id, # 若容器设置了分区键,需添加该参数,值为对应文档的分区键值 # partition_key=whatever, patch_operations=[ { "op": "replace", "path": "/property", "value": newProperty } ] ) except exceptions.CosmosHttpResponseError as e: print(f"Failed to update record. Details: {e.message}")
方案2:构造完整文档再替换
如果必须使用replace_item或upsert_item,需要保证body包含原文档的所有字段。要么查询时拉取全量文档(SELECT * FROM c ...),要么从其他渠道获取完整字段后构造对象,再执行替换操作——这也是你之前查询完整记录后操作正常的原因。
内容的提问来源于stack exchange,提问作者S.Ptr
相关产品推荐
相关产品推荐

