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

调用Dynamodb时PUT请求正常但GET请求失败的问题排查

问题描述
  • PUT请求可正常执行,但所有GET请求均失败:
    • 指定路径参数调用GET /items/{id}时,返回错误:

      "An error occurred (ValidationException) when calling the GetItem operation: The provided key element does not match the schema"

    • 使用curl <link>调用GET /items获取全量数据时,返回:

      {"message":"Internal Server Error"}

完整代码
import json
import boto3
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb')
table_name = 'my-table'
table = dynamodb.Table(table_name)

key = {
    'id': {
        'S': '1'
    }
}

def handler(event, context):
    body = None
    status_code = 200
    headers = {
        'Content-Type': 'application/json',
    }

    try:
        # Based on API Gateway Payload v2.0
        if event['routeKey'] == 'PUT /items':
            request_json = json.loads(event['body'])
            put = table.put_item(
                    Item=request_json
            )
            body = f"Put item with id: {request_json['id']}"

        # Get all items 
        elif event['routeKey'] == 'GET /items':
            scan = table.scan()
            items = scan.get('Items', [])
            body = items

        # Get an item based on the path parameter
        elif event['routeKey'] == 'GET /items/{id}':
            path_parameters = event['pathParameters']
            id_value = path_parameters['id']
            get = table.get_item(
                    Key={
                        'id': {
                            'S': id_value
                            }
                        }
                    )
            body = get.get('Item', None)

        # Delete an item based on the path parameter    
        elif event['routeKey'] == 'DELETE /items/{id}':
            id_value = path_parameters['id']
            delete = table.delete_item(
                Key={
                    'id': id_value
                }
            )
            body = f"Deleted item with id: {id_value}"

        else:   
            raise Exception(f"Unsupported route: {event['routeKey']}")
    except ClientError as e:
        status_code = 400
        body = str(e)
    finally:
        body = json.dumps(body)

    return {
        'statusCode': status_code,
        'body': body,
        'headers': headers,
    }
问题分析与修复

核心问题1:GetItem的Key格式错误

使用boto3的resource模式操作DynamoDB时,无需手动指定数据类型标记(如{'S': id_value}),resource层会自动处理类型映射。你在PUT请求中直接传入request_json成功,说明表的id字段是字符串类型,因此GET请求的Key只需传{'id': id_value}即可,多余的类型标记会导致Schema不匹配的ValidationException。

核心问题2:DELETE路由变量未定义

DELETE分支中直接使用了path_parameters变量,但该变量仅在GET /items/{id}分支中定义,会触发NameError,且原代码未捕获非ClientError的异常,导致未处理的错误返回500状态码。

修复后的代码

import json
import boto3
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb')
table_name = 'my-table'
table = dynamodb.Table(table_name)

def handler(event, context):
    body = None
    status_code = 200
    headers = {
        'Content-Type': 'application/json',
    }

    try:
        if event['routeKey'] == 'PUT /items':
            request_json = json.loads(event['body'])
            table.put_item(Item=request_json)
            body = f"Put item with id: {request_json['id']}"

        elif event['routeKey'] == 'GET /items':
            scan_response = table.scan()
            body = scan_response.get('Items', [])

        elif event['routeKey'] == 'GET /items/{id}':
            path_parameters = event['pathParameters']
            id_value = path_parameters['id']
            get_response = table.get_item(Key={'id': id_value})
            body = get_response.get('Item', None)

        elif event['routeKey'] == 'DELETE /items/{id}':
            path_parameters = event['pathParameters']
            id_value = path_parameters['id']
            table.delete_item(Key={'id': id_value})
            body = f"Deleted item with id: {id_value}"

        else:   
            raise Exception(f"Unsupported route: {event['routeKey']}")
    except ClientError as e:
        status_code = 400
        body = str(e)
    except Exception as e:
        status_code = 500
        body = str(e)
    finally:
        body = json.dumps(body)

    return {
        'statusCode': status_code,
        'body': body,
        'headers': headers,
    }

修复要点说明

  1. 移除GET /items/{id}中Key的类型标记,改为符合resource模式的简洁写法。
  2. 在DELETE /items/{id}分支中新增path_parameters = event['pathParameters'],避免变量未定义错误。
  3. 新增普通Exception捕获,处理所有非ClientError的异常(如变量未定义、路由错误),返回500状态码并输出错误信息,便于排查。
  4. 优化变量命名(如scan改为scan_response),提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:20:19