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

使用Python在Lambda中查询DynamoDB时出现内部服务器错误

问题描述

我正在尝试通过API Gateway的Lambda代理集成,读取分区键为Name的DynamoDB表saved_measurements。已经确认event['pathParameters']['name']功能正常,排除了这个因素的影响。但通过Name查询表时,会返回错误:{"message": "Internal server error"}。我查了很多DynamoDB查询的资料都没解决,当响应体返回示例字符串(比如"yes")时一切正常,只有返回查询数据时才会触发这个错误。该怎么解决?

import json
import boto3
from boto3.dynamodb.conditions import Key, Attr

def lambda_handler(event, context):
  client = boto3.resource('dynamodb')
  table = client.Table('saved_measurements')

  data = table.query(KeyConditionExpression=Key('Name').eq(event['pathParameters']['name']))
  stuff = data.Items

  response = {
    "statusCode": 200,
    "headers": {
      "Content-Type": 'application/json',
      "Access-Control-Allow-Origin" : "*",
      "Access-Control-Allow-Headers" : "Content-Type",
      "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
    },
    "body": json.dumps(stuff),
    "isBase64Encoded": False
  }
  
  return response
解决方向

1. 修复DynamoDB结果的序列化问题

DynamoDB返回的数据中常包含Decimal等Python标准JSON编码器无法处理的类型,这是触发内部错误的最常见原因。可以自定义编码器解决:

import json
from decimal import Decimal

class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Decimal):
            # 根据数值类型转换为int或float
            return int(o) if o % 1 == 0 else float(o)
        return super().default(o)

然后在序列化时指定该编码器:

"body": json.dumps(stuff, cls=DecimalEncoder),

2. 修正结果集的访问方式

原代码中stuff = data.Items是错误的,boto3资源模式下table.query()返回的是字典对象,需通过键名访问结果列表:

stuff = data['Items']

3. 添加错误捕获与日志输出

Lambda内部错误需要查看CloudWatch日志定位,添加异常捕获可以直接返回错误信息,便于排查:

def lambda_handler(event, context):
    try:
        client = boto3.resource('dynamodb')
        table = client.Table('saved_measurements')
        data = table.query(KeyConditionExpression=Key('Name').eq(event['pathParameters']['name']))
        stuff = data['Items']
        
        response = {
            "statusCode": 200,
            "headers": {
                "Content-Type": 'application/json',
                "Access-Control-Allow-Origin" : "*",
                "Access-Control-Allow-Headers" : "Content-Type",
                "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
            },
            "body": json.dumps(stuff, cls=DecimalEncoder),
            "isBase64Encoded": False
        }
        return response
    except Exception as e:
        # 打印日志到CloudWatch
        print(f"Query failed: {str(e)}")
        return {
            "statusCode": 500,
            "headers": {
                "Content-Type": 'application/json',
                "Access-Control-Allow-Origin" : "*",
                "Access-Control-Allow-Headers" : "Content-Type",
                "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
            },
            "body": json.dumps({"error": str(e)}),
            "isBase64Encoded": False
        }

4. 验证Lambda执行角色权限

确保Lambda的执行角色拥有dynamodb:Query权限,且资源范围包含目标表。示例权限策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "dynamodb:Query",
            "Resource": "arn:aws:dynamodb:你的AWS区域:你的账号ID:table/saved_measurements"
        }
    ]
}

5. 确认分区键的大小写匹配

DynamoDB的属性名区分大小写,需确保表的分区键确实是Name(而非name或其他变体)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:55:18