You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic序列化时忽略Field中的特定参数?

问题:FastAPI中Filter模型的Field参数序列化错误

需求目标

我希望根据条件筛选书籍,筛选逻辑是将值与数据库列进行比较。于是设计了不同类型的筛选器处理筛选值,再构建Filter模型,通过FastAPI让用户填充筛选器对象并获取筛选结果。

当前可行实现

# filtering.py

from pydantic import BaseModel, Field
from my_sqlalchemy_models import Book, User


class EqualityFilter(BaseModel):
    value: int
    _column: Any | None = PrivateAttr(default=None)

    def __init__(self, **data):
        super().__init__(**data)
        self._column = data.get("_column")

    @property
    def column(self):
        return self._column

class MinMaxFilter:
    ...

class ContainsFilter:
   ...

class Filter(BaseModel):
    author_id: EqualityFilter | None = Field(default=None, column=Book.author_id)
    owner_id: EqualityFilter | None = Field(default=None, column=User.id)
    owner_name: ContainsFilter | None = Field(default=None, column=User.name)
    price: MinMaxFilter | None = Field(default=None, column=Book.price)

    @model_validator(mode="before")
    @classmethod
    def add_columns(cls, data: Any):
        for field_name, value in cls.model_fields.items():
            schema_extra = value.json_schema_extra
            if field_name in data and schema_extra and schema_extra.get("column") is not None:
                data[field_name]["_column"] = value.json_schema_extra["column"]

        return data

本地运行时可正常创建筛选器对象:

>>> my_filter = Filter(author_id={"value": 1}, owner_name={"value": "John"}, price={"min": 10})
>>> my_filter.author_id.column
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x105933420>

也能生成SQLAlchemy查询的.where条件:

>>> my_filter.author_id.column == my_filter.author_id.value
<sqlalchemy.sql.elements.BinaryExpression object at 0x102bfc860>

遇到的问题

在FastAPI应用中使用Filter模型时,FastAPI生成/docs的openapi.json时无法序列化Field中的column参数,报错:

File "***/.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 2250, in json_schema_update_func
    add_json_schema_extra(json_schema, json_schema_extra)
  File "***/.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 2260, in add_json_schema_extra
    json_schema.update(to_jsonable_python(json_schema_extra))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'sqlalchemy.orm.attributes.InstrumentedAttribute'>

该column参数仅用于内部逻辑,不需要序列化。现需解决:

  • 能否在序列化时忽略Field中的特定参数?
  • 若当前思路不可行,有哪些替代方案?

最小复现示例

运行以下代码python app.py,访问http://127.0.0.1:8000/docs即可看到错误(示例中将SQLAlchemy模型替换为不可序列化的int,报错信息略有不同但原因一致):

from typing import Any

from fastapi import FastAPI
from pydantic import BaseModel, Field, PrivateAttr, model_validator


class EqualityFilter(BaseModel):
    value: int
    _column: Any | None = PrivateAttr(default=None)

    def __init__(self, **data):
        super().__init__(**data)
        self._column = data.get("_column")

    @property
    def column(self):
        return self._column


class Filter(BaseModel):
    author_id: EqualityFilter | None = Field(default=None, column=int)
    owner_id: EqualityFilter | None = Field(default=None, column=int)

    @model_validator(mode="before")
    @classmethod
    def add_columns(cls, data: Any):
        for field_name, value in cls.model_fields.items():
            schema_extra = value.json_schema_extra
            if field_name in data and schema_extra and schema_extra.get("column") is not None:
                data[field_name]["_column"] = value.json_schema_extra["column"]

        return data


app = FastAPI()


@app.post("/books")
async def get_books(filter: Filter):
    # do the filtering
    result = []
    return result


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="127.0.0.1", port=8000)

内容的提问来源于stack exchange,提问作者sahinakkaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:38:11