FastAPI Pydantic多对多关系定义与循环导入错误解决方法
问题根源
你的两个schema模块形成了双向循环导入:supplier_schema.py导入category_schema.py的Category类,而category_schema.py又反过来导入supplier_schema.py的Supplier类,Python导入模块时两个模块都处于未完全初始化的状态,因此抛出导入错误。
另外注意你粘贴的category_schema.py代码存在复制失误,实际逻辑应该是在Category模型中定义了关联Supplier的多对多字段。
修复方案
Pydantic原生支持前向引用解决循环导入问题,按以下步骤修改即可:
第一步:移除循环导入,使用字符串类型标注
不要在文件顶部互相导入对方的模型类,将关联字段的类型用字符串包裹(前向引用):
修改后seller_schema.py代码
from pydantic import BaseModel, HttpUrl, EmailStr from typing import Optional, List from datetime import datetime # 删掉原来的 from schemas.category_schema import Category from schemas.membership_schema import Membership class SupplierBase(BaseModel): contact_person: str email_address: EmailStr company_name: str company_email: str company_logo: str country: str state_province: str city_area: Optional[str] = None location: str phone: str fax: Optional[str] = None tagline: str company_bio: Optional[str] year_established: int employees_count: str certificates: Optional[List[str]] = None cover_image: Optional[HttpUrl] = None gallery: Optional[List[HttpUrl]] = None company_license: Optional[HttpUrl] = None company_website: Optional[HttpUrl] = None whatsapp_number: Optional[str] = None facebook_url: Optional[HttpUrl] = None twitter_url: Optional[HttpUrl] = None linkedin_url: Optional[HttpUrl] = None pinterest_url: Optional[HttpUrl] = None instagram_url: Optional[HttpUrl] = None youtube_url: Optional[HttpUrl] = None annual_revenue: Optional[str] = None challenges: List[str] status: str = None class Config: orm_mode = True class SupplierCreate(SupplierBase): password: str membership_id: int categories_id: Optional[List[int]] = [] class Supplier(SupplierBase): id: int created_at: datetime updated_at: datetime membership: Membership categories: List["Category"] # 用字符串包裹前向引用类型 # 新增:更新前向引用解析 Supplier.update_forward_refs()
修改后category_schema.py代码(修正粘贴错误的逻辑后)
from pydantic import BaseModel from typing import Optional, List from datetime import datetime # 删掉原来的 from schemas.supplier_schema import Supplier class CategoryBase(BaseModel): name: str # 其他你自定义的Category字段 class Config: orm_mode = True class Category(CategoryBase): id: int created_at: datetime updated_at: datetime suppliers: List["Supplier"] # 用字符串包裹前向引用类型 # 新增:更新前向引用解析 Category.update_forward_refs()
可选:Pydantic V2简化方案
如果你使用Pydantic V2,可以在文件最顶部加from __future__ import annotations,不需要给类型加引号,直接写原生类型即可,后续同样调用update_forward_refs更新引用:
from __future__ import annotations # 其他导入代码 class Supplier(SupplierBase): id: int created_at: datetime updated_at: datetime membership: Membership categories: List[Category] # 不需要加引号 Supplier.update_forward_refs()
内容的提问来源于stack exchange,提问作者Natnael
相关产品推荐
相关产品推荐

