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

FastAPI创建用户接口返回UserResponse触发Pydantic验证错误

问题:FastAPI创建用户接口返回时触发Pydantic验证错误

问题背景

使用FastAPI编写的创建用户接口能成功将数据写入数据库,但返回结果时触发Pydantic验证错误,提示first_name、email、created_at字段缺失。

接口代码

@router.post("/", response_model=schemas.UserResponse)
def create_user(user: schemas.UserCreate):
    conn, cursor = get_db()
    query = """SELECT * FROM users WHERE u_email = %s;"""
    value = (user.email,)
    cursor.execute(query, value)
    row = cursor.fetchone()
    cursor.close()
    conn.close()
    if row is not None:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"This email already exists")

    # Create the hash of the user password
    hashed_password = utils.hash(user.password)
    user.password = hashed_password

    # Create the user
    conn, cursor = get_db()
    query = """INSERT INTO users (u_fname, u_email, u_password) VALUES (%s, %s, %s) RETURNING *;"""
    values = (user.first_name, user.email, user.password)
    cursor.execute(query, values)
    new_user = cursor.fetchone()
    conn.commit()
    cursor.close()
    conn.close()
    
    return new_user

Pydantic模型代码

class UserBase(BaseModel):
    first_name: constr(min_length=1)
    email: EmailStr


class UserCreate(UserBase):
    password: str


class UserResponse(UserBase):
    created_at: datetime

    class Config:
        orm_mode = True

错误信息

pydantic.error_wrappers.ValidationError: 3 validation errors for UserResponse
response -> first_name
  field required (type=value_error.missing)
response -> email
  field required (type=value_error.missing)
response -> created_at
  field required (type=value_error.missing)

原因分析

核心问题是数据库游标返回的数据格式与Pydantic模型的字段映射不匹配:

  • 普通游标执行fetchone()后返回的是元组,仅包含字段值,没有字段名信息;
  • Pydantic的UserResponse模型需要键值对形式的数据(字典或ORM对象)来匹配字段名;
  • 开启的orm_mode = True仅适配ORM对象(如SQLAlchemy实例),对普通元组无效,因此模型无法识别元组中的值对应哪个字段,导致字段缺失错误。

解决方法

方案1:使用字典游标

修改get_db()方法,配置游标返回字典格式,让fetchone()直接返回带字段名的键值对:

# 以psycopg2为例,其他数据库驱动语法略有不同
def get_db():
    conn = psycopg2.connect(
        dbname="your_db",
        user="your_user",
        password="your_pw",
        host="your_host"
    )
    # 设置字典游标
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    try:
        yield conn, cursor
    finally:
        cursor.close()
        conn.close()

不同数据库驱动的字典游标设置:

  • MySQLdb:cursorclass=MySQLdb.cursors.DictCursor
  • sqlite3:cursor = conn.cursor(row_factory=sqlite3.Row)(返回的Row对象可通过键名访问)

方案2:手动映射元组为字典

如果不想修改游标配置,可在获取结果后手动将元组转换为符合模型要求的字典:

new_user = cursor.fetchone()
# 需与RETURNING *返回的字段顺序严格对应,示例假设顺序为u_fname, u_email, u_password, created_at
new_user_dict = {
    "first_name": new_user[0],
    "email": new_user[1],
    "created_at": new_user[3]
}
return new_user_dict

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:12:22