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

如何修复Lambda从DynamoDB获取指定列的参数验证错误?

问题分析:Lambda函数从DynamoDB获取指定字段失败

问题描述

我希望通过Lambda函数从DynamoDB中仅获取timestamp、address、distance和proximity字段,通过API Gateway返回响应给React Native应用展示,但当前代码运行报错,请问代码存在什么问题?

原代码

import boto3
import json

from boto3.dynamodb.conditions import Key, Attr

def lambda_handler(event, context):

    IRAPID_BEACON = 'irapid_beacon'
    
    DDB_RESOURCE = boto3.resource('dynamodb')
    IRAPID_BEACON_DDB_TABLE = DDB_RESOURCE.Table(IRAPID_BEACON)
    
    result = IRAPID_BEACON_DDB_TABLE.get_item(Key={'timestamp'}, ProjectionExpression='#timestamp, address, distance, proximity', ExpressionAttributeNames={'#address': 'address'})
    
    return {
        'body': result
    }

错误响应(已翻译)

{
  "errorMessage": "参数验证失败:\nKey参数类型无效,值: {'timestamp'}, 类型: <class 'set'>, 合法类型: <class 'dict'>",
  "errorType": "参数验证错误",
  "requestId": "3af15dff-d323-49bf-9429-bfce2d26e579",
  "stackTrace": [
    "  文件 \"/var/task/lambda_function.py\", 第14行, 在lambda_handler函数中\n    result = IRAPID_BEACON_DDB_TABLE.get_item(Key={'timestamp'}, ProjectionExpression='#timestamp, address, distance, proximity', ExpressionAttributeNames={'#address': 'address'})\n",
    "  文件 \"/var/runtime/boto3/resources/factory.py\", 第520行, 在do_action函数中\n    response = action(self, *args, **kwargs)\n",
    "  文件 \"/var/runtime/boto3/resources/action.py\", 第83行, 在__call__函数中\n    response = getattr(parent.meta.client, operation_name)(*args, **params)\n",
    "  文件 \"/var/runtime/botocore/client.py\", 第391行, 在_api_call函数中\n    return self._make_api_call(operation_name, kwargs)\n",
    "  文件 \"/var/runtime/botocore/client.py\", 第691行, 在_make_api_call函数中\n    request_dict = self._convert_to_request_dict(\n",
    "  文件 \"/var/runtime/botocore/client.py\", 第739行, 在_convert_to_request_dict函数中\n    request_dict = self._serializer.serialize_to_request(\n",
    "  文件 \"/var/runtime/botocore/validate.py\", 第360行, 在serialize_to_request函数中\n    raise ParamValidationError(report=report.generate_report())\n"
  ]
}

代码问题分析

  1. Key参数格式错误:get_item要求传入完整的主键键值对字典,你写的{'timestamp'}是集合类型,完全不符合要求。如果timestamp是表的主键,需要传入{'timestamp': '具体时间值'};如果是复合主键,还要加上排序键的键值对(比如{'timestamp': 'xxx', 'id': 'yyy'})。
  2. ProjectionExpression别名逻辑颠倒:你给timestamp用了#timestamp别名,但没在ExpressionAttributeNames里定义;反而给不需要别名的address定义了别名,逻辑完全错误。timestamp不是DynamoDB保留字,其实不需要别名,若一定要用别名,需在字典中添加{'#timestamp': 'timestamp'}。
  3. 返回格式不符合API Gateway要求:API Gateway要求Lambda返回的body是JSON字符串,直接返回result字典会导致序列化失败,必须用json.dumps()转换。
  4. API选择潜在错误:如果你的需求是获取多条记录,get_item只适合获取单条主键匹配的记录,应该改用scan或query方法。

修正后的代码

情况1:获取单条已知主键的记录

import boto3
import json

def lambda_handler(event, context):
    IRAPID_BEACON = 'irapid_beacon'
    DDB_RESOURCE = boto3.resource('dynamodb')
    table = DDB_RESOURCE.Table(IRAPID_BEACON)
    
    # 替换成实际要查询的timestamp值
    target_timestamp = "2024-05-20T12:00:00"
    
    try:
        # 正确传入主键键值对,按需指定返回字段
        response = table.get_item(
            Key={'timestamp': target_timestamp},
            ProjectionExpression='timestamp, address, distance, proximity'
        )
        # 提取Item,处理记录不存在的情况
        item = response.get('Item', {})
        return {
            'statusCode': 200,
            'body': json.dumps(item)
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

情况2:获取多条记录(比如所有符合条件的)

import boto3
import json

def lambda_handler(event, context):
    IRAPID_BEACON = 'irapid_beacon'
    DDB_RESOURCE = boto3.resource('dynamodb')
    table = DDB_RESOURCE.Table(IRAPID_BEACON)
    
    try:
        # 用scan获取所有记录,指定返回字段
        response = table.scan(
            ProjectionExpression='timestamp, address, distance, proximity'
        )
        items = response.get('Items', [])
        # 处理分页(数据量大时需循环获取剩余数据)
        while 'LastEvaluatedKey' in response:
            response = table.scan(
                ProjectionExpression='timestamp, address, distance, proximity',
                ExclusiveStartKey=response['LastEvaluatedKey']
            )
            items.extend(response['Items'])
        
        return {
            'statusCode': 200,
            'body': json.dumps(items)
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:00:04