最近刚开始学 python 和 fastapi, 按照 fastapi 教程学习时遇到个问题, 因为使用 sqlmodel 的 relationship, 导致两个模型文件相互导入, 然后报错了, 根据官方文档的解决办法, 使用 TYPE_CHECKING 和字符串版本类型后暂时解决了报错.
但是当接口通过 response_model 指定了数据模型(非表模型)作为返回类型时, 又出现了报错, 报错提示如下:
`TypeAdapter[typing.Annotated[app.models.teams.TeamPublicWithUser, FieldInfo(annotation=TeamPublicWithUser, required=True)]]` is not fully defined; you should define `typing.Annotated[app.models.teams.TeamPublicWithUser, FieldInfo(annotation=TeamPublicWithUser, required=True)]` and all referenced types, then call `.rebuild()` on the instance.
求各位大佬帮忙看看, 哪里有问题.
python 版本用的是 3.12, 具体代码如下
models/users.py
from typing import TYPE_CHECKING, Any, Optional
from sqlmodel import Field, Relationship, SQLModel
if TYPE_CHECKING:
from .teams import Team, TeamPublic
class UserBase(SQLModel):
username: str = Field(index=True, max_length=255, unique=True)
email: str | None = Field(default=None, index=True, max_length=255)
is_active: bool = True
is_superuser: bool = False
full_name: str | None = Field(default=None, max_length=255)
team_id: int | None = Field(default=None, foreign_key="team.id")
class User(UserBase, table=True):
id: int | None = Field(default=None, primary_key=True)
hashed_password: str
team: Optional["Team"] = Relationship(back_populates="members")
class UserPublic(UserBase):
id: int
class UserPublicWithTeam(UserPublic):
team: Optional["TeamPublic"] = None
models/teams.py
from typing import TYPE_CHECKING, Any, List
from sqlmodel import Field, Relationship, SQLModel
if TYPE_CHECKING:
from .users import User, UserPublic
class TeamBase(SQLModel):
name: str = Field(max_length=255)
class Team(TeamBase, table=True):
id: int | None = Field(default=None, primary_key=True)
members: List["User"] = Relationship(back_populates="team")
class TeamPublic(TeamBase):
id: int
class TeamPublicWithUser(TeamPublic):
members: List["UserPublic"] = []
router/users.py
# 用户相关接口
from sqlmodel import and_, select
from app.api.deps import SessionDep
from app.models.users import (
User,
UserPublicWithTeam,
)
from app.new_router import new_router
router = new_router(prefix="/users", tags=["用户管理"])
@router.get("/{id}", summary="获取用户详情", response_model=UserPublicWithTeam)
async def get_user_api(db: SessionDep, id: int):
user = db.exec(select(User).where(and_(User.id == id, User.is_active))).first()
return user
router/teams.py
# 团队相关接口
from sqlmodel import select
from app.api.deps import SessionDep
from app.models.teams import (
Team,
TeamPublicWithUser,
)
from app.new_router import new_router
router = new_router(prefix="/teams", tags=["团队管理"])
@router.get("/{id}", summary="获取团队详情", response_model=TeamPublicWithUser)
async def get_team_api(db: SessionDep, id: int):
team = db.exec(select(Team).where(Team.id == id)).first()
return team
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.