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

如何通过Alexa Skill的DynamoDB Adapter迭代更新嵌套属性

问题:Alexa技能中DynamoDB嵌套属性更新失败

我正在为Alexa技能使用DynamoDB Adapter,刚接触开发,问题可能比较基础。

我要持久化的嵌套属性初始格式如下:

enqueue_data = {
    "ENQUEUE": [
        {
            "link_enqueue": "http://link1.com",
            "offset_in_milliseconds_enqueue": "numerical value",
            "title": "title 1"
        },
        {
            "link_enqueue": "http://link2.com",
            "offset_in_milliseconds_enqueue": "numerical value",
            "title": "title 2"
        }
    ]
}

但在DynamoDB中实际存储的格式是:

{ 
    "link" : { "S" : "http://link1.com" },
    "ENQUEUE" : { 
        "L" : [ 
            { 
                "M" : { 
                    "title_enqueue" : { "S" : "Title 1" }, 
                    "link_enqueue" : { "S" : "http://link1.com" }, 
                    "offset_in_milliseconds_enqueue" : { "N" : "15645" } 
                } 
            }, 
            { 
                "M" : { 
                    "title_enqueue" : { "S" : "title 2" }, 
                    "link_enqueue" : { "S" : "http://link2.com" }, 
                    "offset_in_milliseconds_enqueue" : { "N" : "52546" } 
                } 
            }
        ]
    }
}

我已经通过selected_link = attr['link']成功获取到了selected_link变量,现在需要实现以下逻辑:

  • 判断ENQUEUE键是否存在;
  • 若存在,遍历ENQUEUE中的link_enqueue值,找到与selected_link匹配的项;
  • 匹配成功则更新该项的offset_in_milliseconds_enqueue值。

举个例子:当selected_link为http://link1.com时,找到ENQUEUE中对应项,将其offset_in_milliseconds_enqueue更新为新值。

我写了如下Python代码,但没达到预期效果:

def handle(self, handler_input):
    offset_in_milliseconds = '3232'
    
    # 获取dynamodb中的属性
    attr = handler_input.attributes_manager.persistent_attributes
    
    # 获取link值
    selected_link = attr['link']

    # 检查持久化属性中是否存在'ENQUEUE'键
    if 'ENQUEUE' in attr:
        enqueue_data = attr['ENQUEUE']

        # 检查ENQUEUE中是否有项包含匹配的link_enqueue
        relevant_items = [item for item in enqueue_data.values() if item.get('link_enqueue') == selected_link]

        if relevant_items:
            relevant_item = relevant_items[0]  
            # 假设取第一个匹配项
            relevant_item['offset_in_milliseconds_enqueue'] = offset_in_milliseconds
            # 保存更新后的持久化属性
            handler_input.attributes_manager.save_persistent_attributes()
            return
        return
    return

我期望更新后只有目标项的offset值变更,其余内容保持不变,预期格式如下:

enqueue_data = {
    "ENQUEUE": [
        {
            "link_enqueue": "http://link1.com",
            "offset_in_milliseconds_enqueue": "new numerical value",
            "title": "title 1"
        },
        {
            "link_enqueue": "http://link2.com",
            "offset_in_milliseconds_enqueue": "numerical value",
            "title": "title 2"
        }
    ]
}

解决方案

你的代码核心问题在于对enqueue_data的类型判断错误:attr['ENQUEUE']对应的是列表(对应DynamoDB中的L类型),而非字典,所以不能用enqueue_data.values()来遍历,直接遍历列表即可。另外注意DynamoDB中offset_in_milliseconds_enqueue是数字类型(N),如果你的新值是字符串,建议转为整数或保持数字类型,避免类型不匹配。

修改后的代码如下:

def handle(self, handler_input):
    # 注意:如果DynamoDB中存储的是数字类型,这里用整数更合适
    offset_in_milliseconds = 3232
    
    attr = handler_input.attributes_manager.persistent_attributes
    selected_link = attr['link']

    if 'ENQUEUE' in attr:
        enqueue_list = attr['ENQUEUE']
        # 遍历ENQUEUE列表中的每一项
        for item in enqueue_list:
            if item.get('link_enqueue') == selected_link:
                # 更新offset值,注意类型匹配
                item['offset_in_milliseconds_enqueue'] = offset_in_milliseconds
                # 保存更新
                handler_input.attributes_manager.save_persistent_attributes()
                # 找到匹配项后即可退出循环,避免多余遍历
                break
    return

关键修改点:

  1. 把enqueue_data.values()改为直接遍历enqueue_list(因为attr['ENQUEUE']是列表);
  2. 遍历过程中找到匹配项就更新并break,提升效率;
  3. 调整offset值的类型为数字,和DynamoDB中存储的N类型对应(如果业务需要字符串类型,可以改回字符串,但建议保持类型一致)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:16:14