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

FastAPI结合DynamoDb put_item插入失败问题排查咨询

问题解决步骤

一、先修正put_item的Item格式问题

核心错误:

你的代码把student_id作为Item的键、整个学生对象作为值,不符合DynamoDB的Item格式要求——DynamoDB的Item必须包含表定义的主键字段(假设你的表myTable主键是student_id,类型为数字);同时Pydantic模型的转换方式错误,不能直接用json.loads()处理Pydantic实例。

修正后的create_student函数:

from pydantic import BaseModel
import boto3
from botocore.exceptions import ClientError

class Student(BaseModel):
    name: str 
    age: int 
    year: str

def connect_ddb():
    ddb = boto3.resource('dynamodb', region_name='us-west-2')
    table = ddb.Table('myTable')
    return table 

@app.post('/create-student/{student_id}')
def create_student(student_id : int, student : Student):
    db = connect_ddb()
    # 正确转换Pydantic模型为字典(v2用model_dump,v1用dict)
    student_data = student.model_dump()
    try:
        # 按照表的主键结构构造Item
        db.put_item(
            Item = {
                "student_id": student_id,  # 主键字段必须和表定义完全一致
                **student_data  # 展开学生属性,如需嵌套可改为"student_info": student_data
            }
        )
        # get_item需指定Key参数,不能直接传student_id
        response = db.get_item(Key={"student_id": student_id})
        return response.get("Item", {"message": "学生创建成功,但未查询到数据"})
    except ClientError as e:
        # 返回DynamoDB具体错误信息
        return {"error": "DynamoDB操作失败", "details": e.response['Error']['Message']}
    except Exception as e:
        # 捕获其他未知异常并返回详情
        return {"error": "未知错误", "details": str(e)}

关键说明:

  1. 主键匹配:确保Item中的主键字段名、类型和DynamoDB表的定义完全一致,不能把主键值作为键名使用。
  2. Pydantic转换:用model_dump()(Pydantic v2)或dict()(Pydantic v1)将模型转为字典,不要用json.loads()处理Pydantic实例。
  3. get_item用法:必须传入Key参数指定主键的键值对,不能直接传主键值。

二、让FastAPI返回DynamoDB具体错误的方法

通过捕获botocore.exceptions.ClientError异常——这是boto3操作DynamoDB时抛出的专属异常,其中包含DynamoDB返回的详细错误描述(比如主键重复、权限不足、表不存在等)。

在except ClientError as e:代码块中,通过e.response['Error']['Message']提取具体错误信息,返回给前端即可定位问题。

三、测试代码的修正

测试代码同样存在Item格式错误,修正后如下:

def put(item, id_, db):
    # 无需json.dumps,直接构造符合表结构的Item
    db.put_item(Item={
        "student_id": id_,
        **item
    })

# 调用示例
db = connect_ddb()
put(id_=4, item={
    "name": "Guy",
    "age": 17,
    "year": "year 12"
}, db=db)

额外排查点

  1. 确认DynamoDB表myTable的主键定义(字段名、类型)和代码完全匹配。
  2. 确认执行代码的IAM角色/用户拥有dynamodb:PutItem和dynamodb:GetItem权限。
  3. 若使用本地DynamoDB,检查连接配置(如endpoint_url)是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:00:26