FastAPI无法将SQLModel模型作为路由返回类型的问题求助
我最近在跟着FastAPI的文档开发API,文档里用SQLModel定义了Hero模型,还说明这个模型本质上就是一个Pydantic模型,可以直接用作路由的返回类型。不过我发现文档里的@app.on_event("startup")装饰器已经过时了,按照编辑器提示换成了lifespan事件。
但当我照着文档的写法,把Hero模型作为路由返回类型时,Python抛出了如下错误:
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <module 'models.Hero' from 'C:...\Hero.py'> is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/
我的项目结构如下:
src ├── app.py ├── models │ └── Hero.py └── service └── db_config.py
启动API使用的命令是:
$ uvicorn app:app --reload --host 0.0.0.0 --port 8080
以下是各个文件的代码:
app.py
from fastapi import FastAPI, Query from typing import Annotated from fastapi.responses import JSONResponse from service.db_config import engine, SessionDep, create_db_and_tables from contextlib import asynccontextmanager from sqlmodel import select from models import Hero @asynccontextmanager async def lifespan(app: FastAPI): print("Startup") create_db_and_tables() yield print("Shutdown") app = FastAPI(lifespan=lifespan) @app.get("/") def get_welcome_message(): return JSONResponse( content={ "message": "Welcome to my API" }, status_code=200 ) @app.post("/heroes") def create_hero(hero: Hero, session: SessionDep) -> Hero: session.add(hero) session.commit() session.refresh(hero) return JSONResponse( content=hero, status_code=200 ) @app.get("/heroes") def get_heroes(session: SessionDep, offset: int = 0, limit: Annotated[int, Query(le=100)] = 100) -> list[Hero]: heroes = session.exec(select(Hero).offset(offset).limit(limit)).all() return JSONResponse( content=heroes, status_code=200 )
db_config.py
from typing import Annotated from fastapi import Depends from sqlmodel import Session, create_engine, SQLModel def get_session(): with Session(engine) as session: yield session def create_db_and_tables(): SQLModel.metadata.create_all(engine) db_engine = "postgresql" db_user = "postgresql" db_user_password = "ADMIN" db_address = "127.0.0.1" db_name = "realm" connect_args = {"check_same_thread": False} db_url = f"{db_engine}://{db_user}:{db_user_password}@{db_address}/{db_name}" engine = create_engine(url=db_url, connect_args=connect_args) SessionDep = Annotated[Session, Depends(get_session)]
Hero.py
from sqlmodel import Field, SQLModel,table class Hero(SQLModel, table=True): id: str = Field(primary_key=True, nullable=False) name: str = Field(nullable=False) age: int = Field(nullable=False)
请问我该如何解决这个问题呢?
备注:内容来源于stack exchange,提问作者Benevos

