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

DynamoDB更新含保留字嵌套属性报错:#buyer未定义

解决DynamoDB更新嵌套对象(含保留关键字)时的自动创建问题

问题背景

现有DynamoDB条目:

{
   "id":1,
   "poc_name": "ABC"
}

需要更新为:

{
    "id": 1,
    "poc_name": "ABC",
    "buyer": {
        "value": "id1",
        "label": "Test"
    }
}

因使用保留关键字value,且buyer对象不存在时,更新触发报错:

An expression attribute name used in the document path is not defined; attribute name: #buyer

现有代码生成的更新参数:

updateValues: {':poc_name': 'ABC', ':buyer_value': 'id1', ':buyer_label': 'Test'}
updateExpression: ['set ','poc_name = :poc_name,','#buyer.#value = :buyer_value,', 'buyer.label = :buyer_label,']
expression_attributes_names: {'#demand_poc_action': 'demand_poc_action', '#value': 'value', '#buyer': 'buyer'}

核心代码片段:

for key, value in dictData.items():
        if key in RESERVER_DDB_KEYWORDS or (
            "." in key and key.split(".")[1] in RESERVER_DDB_KEYWORDS
        ):
            key1 = key.replace(".", ".#")
            updateExpression.append(f"#{key1} = :{key.replace('.', '_')},")
            updateValues[f":{key.replace('.', '_')}"] = value
            if "." in key:
                expression_attributes_names[f"#{key.split('.')[0]}"] = key.split(".")[0]
                expression_attributes_names[f"#{key.split('.')[1]}"] = key.split(".")[1]
            else:
                expression_attributes_names[f"#{key}"] = key
        else:
            updateExpression.append(f"{key} = :{key.replace('.', '_')},")
            updateValues[f":{key.replace('.', '_')}"] = value
    
UpdateExpression="".join(updateExpression)[:-1],
ExpressionAttributeValues=updateValues,
ReturnValues="UPDATED_NEW",
ExpressionAttributeNames=expression_attributes_names,

当前问题:buyer对象已存在时更新正常,不存在时触发报错,需求是自动创建buyer但无法修改现有代码。

解决方案

方案1:调整输入数据结构(推荐)

不传入buyer.value、buyer.label这类嵌套键,直接传入完整的buyer对象作为顶层键:
将原来的输入数据:

dictData = {
    "poc_name": "ABC",
    "buyer.value": "id1",
    "buyer.label": "Test"
}

修改为:

dictData = {
    "poc_name": "ABC",
    "buyer": {
        "value": "id1",
        "label": "Test"
    }
}

这样现有代码会直接生成buyer = :buyer的更新语句,DynamoDB会自动创建不存在的buyer对象,且内部的value作为对象属性,无需单独处理保留关键字路径问题。

方案2:前置创建空对象

在原有更新操作前,先执行一次条件更新,确保buyer存在:

  1. 执行前置UpdateItem操作:
    dynamodb.update_item(
        TableName="your-table-name",
        Key={"id": {"N": "1"}},
        UpdateExpression="set #buyer = :empty_obj",
        ConditionExpression="attribute_not_exists(#buyer)",
        ExpressionAttributeNames={"#buyer": "buyer"},
        ExpressionAttributeValues={":empty_obj": {"M": {}}}
    )
    
  2. 再执行原有更新逻辑,此时buyer已存在,不会触发路径不存在的报错。

内容的提问来源于stack exchange,提问作者Neelabh Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:40:32