如何用Pydantic model_validate验证SQLAlchemy关联并避免循环导入
解决方案
方法1:在验证器内部动态导入关联模型
TYPE_CHECKING块内的导入仅在类型检查阶段生效,运行时不会加载模块。将导入操作移到验证器函数内部,仅在需要验证时才导入关联模型,避免循环导入:
修改foo.py的验证器:
@field_validator("y", mode="before") @classmethod def validate_relationship(cls, v: Any): from src.schemas.bar import Bar return Bar.model_validate(v)
修改bar.py的验证器:
@field_validator("b", mode="before") @classmethod def validate_relationship(cls, v: Any): from src.schemas.foo import Foo return Foo.model_validate(v)
方法2:使用Pydantic v2的根验证器(model_validator)
若使用Pydantic v2,可改用根验证器统一处理关联字段验证,同样在验证器内部动态导入:
foo.py示例:
from pydantic import BaseModel, Field, model_validator from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from src.schemas.bar import Bar class Foo(BaseModel): x: int = Field(...) y: "Bar" = Field(...) @model_validator(mode="before") @classmethod def validate_relationships(cls, values: dict[str, Any]) -> dict[str, Any]: from src.schemas.bar import Bar if "y" in values: values["y"] = Bar.model_validate(values["y"]) return values
bar.py同理,在根验证器内部动态导入Foo即可。
方法3:抽离验证逻辑到独立工具模块
创建src/schemas/validators.py模块,统一管理关联模型的验证逻辑,利用动态导入避免循环:
validators.py:
from typing import Any def validate_bar(v: Any): from src.schemas.bar import Bar return Bar.model_validate(v) def validate_foo(v: Any): from src.schemas.foo import Foo return Foo.model_validate(v)
foo.py中使用:
from pydantic import BaseModel, Field, field_validator from typing import TYPE_CHECKING, Any from src.schemas.validators import validate_bar if TYPE_CHECKING: from src.schemas.bar import Bar class Foo(BaseModel): x: int = Field(...) y: "Bar" = Field(...) @field_validator("y", mode="before") @classmethod def validate_relationship(cls, v: Any): return validate_bar(v)
bar.py中导入validate_foo并应用到对应字段的验证器即可。
内容的提问来源于stack exchange,提问作者Sidharth Sharma
相关产品推荐
相关产品推荐

