You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:26:03