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

如何在FastAPI中结合asyncpg将查询结果映射到Pydantic模型实现校验输出

FastAPI + asyncpg 无ORM场景下Pydantic结果映射实现方案

前置依赖

先安装需要的工具包:

pip install fastapi uvicorn asyncpg pydantic

核心原理

asyncpg执行查询返回的Record对象是类字典结构,可直接转换为Python字典,传入Pydantic模型的校验方法即可完成数据校验和结构匹配,接口通过指定response_model即可保证最终返回结构完全符合Schema定义。

完整实现示例

1. 基础代码编写

from datetime import datetime
from typing import Optional, List
from fastapi import FastAPI, Depends, HTTPException
import asyncpg
from pydantic import BaseModel, Field

# 初始化FastAPI实例
app = FastAPI()

# 数据库连接配置,替换为自己的数据库信息
DB_CONFIG = {
    "user": "your_db_user",
    "password": "your_db_pass",
    "database": "your_db_name",
    "host": "127.0.0.1",
    "port": 5432
}

# 数据库连接依赖,自动管理连接释放
async def get_db_conn():
    conn = await asyncpg.connect(**DB_CONFIG)
    try:
        yield conn
    finally:
        await conn.close()

# 定义Pydantic响应Schema,字段名默认和数据库查询返回的列名保持一致
class UserOut(BaseModel):
    id: int
    username: str
    email: str
    create_time: datetime
    # 可选字段标注为Optional,无值时默认返回None
    bio: Optional[str] = None
    # 若数据库列名和Schema字段名不一致,可通过alias指定
    # phone: str = Field(alias="user_phone")

    # Pydantic V2配置,V1版本可删除,改用parse_obj方法校验
    model_config = {
        "from_attributes": True,
        "populate_by_name": True
    }

2. 单条查询接口实现

# 指定response_model为定义的Schema,强制返回结构完全匹配定义
@app.get("/users/{user_id}", response_model=UserOut)
async def get_user(user_id: int, conn: asyncpg.Connection = Depends(get_db_conn)):
    # asyncpg使用$1、$2作为参数占位符,避免SQL注入
    row = await conn.fetchrow(
        "SELECT id, username, email, create_time, bio FROM users WHERE id = $1",
        user_id
    )
    if not row:
        raise HTTPException(status_code=404, detail="用户不存在")
    # Record转字典后传入Pydantic完成校验,V1版本替换为UserOut.parse_obj(dict(row))
    return UserOut.model_validate(dict(row))

3. 批量查询接口实现

@app.get("/users/", response_model=List[UserOut])
async def list_users(conn: asyncpg.Connection = Depends(get_db_conn)):
    rows = await conn.fetch("SELECT id, username, email, create_time, bio FROM users LIMIT 10")
    # 遍历校验所有查询结果
    return [UserOut.model_validate(dict(row)) for row in rows]

特殊场景处理

  • 嵌套结构返回:连表查询得到平展结果后,手动组装为符合嵌套Schema结构的字典,再传入Pydantic模型校验即可
  • 校验规则扩展:可直接在Pydantic字段上添加校验规则(如字符串长度、数值范围等),查询结果会自动执行校验,不符合规则会直接返回422错误
  • 多余字段过滤:Pydantic默认会丢弃Schema未定义的字段,无需手动处理查询返回的冗余列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:45:02