如何通过FastAPI批量插入PostgreSQL并返回自动生成主键ID
解决FastAPI POST插入数据后返回带主键ID的列表问题
步骤1:调整Pydantic模型(规范命名,可选但推荐)
首先修正models.py中的模型定义,明确区分请求模型和响应模型:
# models.py from sqlalchemy.orm import Mapped,mapped_column,DeclarativeBase from sqlalchemy import Identity,Enum from pydantic import BaseModel, ConfigDict import enum class Base(DeclarativeBase): pass class Color(str,enum.Enum): RED = 'RED' BLUE = 'BLUE' class Example(Base): __tablename__='example' id: Mapped[int] = mapped_column(Identity(always=True),primary_key=True) colors: Mapped[Color] = mapped_column(Enum(Color)) # 基础模型,定义公共字段 class ExampleBase(BaseModel): model_config = ConfigDict(from_attributes=True) colors: Color # 请求模型:接收前端提交的数据,无需传入id class ExampleCreate(ExampleBase): pass # 响应模型:返回包含数据库自动生成id的数据 class ExampleResponse(ExampleBase): id: int
步骤2:修改POST路由实现返回功能
以下两种可靠方案任选其一即可:
方案一:用SQLAlchemy Core的returning语句直接获取插入结果
# main.py @app.post("/create_color/", response_model=list[ExampleResponse]) async def create_colors(colors: list[ExampleCreate], db: AsyncSession = Depends(get_db)): # 构建插入语句,指定返回id和colors字段 stmt = insert(Example).values([item.model_dump() for item in colors]).returning(Example.id, Example.colors) # 执行语句并获取插入后的记录 result = await db.execute(stmt) await db.commit() # 将结果转换为Pydantic模型列表返回 inserted_records = result.mappings().all() return [ExampleResponse(**record) for record in inserted_records]
方案二:用SQLAlchemy ORM的对象添加方式
# main.py @app.post("/create_color/", response_model=list[ExampleResponse]) async def create_colors(colors: list[ExampleCreate], db: AsyncSession = Depends(get_db)): # 将请求数据转换为SQLAlchemy对象 example_objects = [Example(**item.model_dump()) for item in colors] # 添加所有对象到数据库会话 db.add_all(example_objects) await db.commit() # 刷新每个对象,获取数据库自动生成的id for obj in example_objects: await db.refresh(obj) # 直接返回对象,FastAPI会自动转换为响应模型 return example_objects
关键说明
- 原代码问题:直接执行
insert语句默认不会返回插入记录,必须显式通过returning指定返回字段,或通过ORM对象刷新获取主键ID。 - 方案对比:
- 方案一更适合批量插入场景,性能略优;
- 方案二更贴合ORM使用习惯,代码更直观。
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

