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

如何让Pydantic不将自定义Enum序列化为字典适配SQLAlchemy

解决Pydantic序列化自定义Enum为Dict导致SQLAlchemy报错的问题

问题分析

你的自定义State枚举同时继承了数据类StateDataMixin和Enum,Pydantic默认会将其序列化为数据类的字段结构(即{'state': {'state': 'Alaska', 'short': 'AK'}}),而SQLAlchemy需要接收State枚举实例才能正确存入数据库,因此触发unhashable type: 'dict'错误。

解决方案

方案1:给Pydantic模型添加自定义序列化器

在你的SomeState(或对应的ItemCreate)模型中,使用model_serializer装饰器,指定序列化时直接返回枚举实例:

class SomeState(BaseModel):
    state: State

    @model_serializer
    def serialize_state(self):
        return {"state": self.state}

调用model_dump()后,结果会是{'state': State.ALASKA},直接适配SQLAlchemy的枚举类型要求。

方案2:为State类型添加Pydantic核心模式

通过为State类实现__get_pydantic_core_schema__方法,告诉Pydantic将其当作枚举类型处理,而非数据类:

from pydantic_core import core_schema

class State(StateDataMixin, Enum):
    ALABAMA = "Alabama", "AL"
    ALASKA = "Alaska", "AK"
    # 其他州枚举项...

    @property
    def value(self):
        return self._value_.state  # type: ignore

    @classmethod
    def __get_pydantic_core_schema__(cls, source_type, handler):
        # 复用枚举的核心校验逻辑
        enum_schema = handler(Enum)
        return core_schema.no_info_wrap_validator_function(
            lambda v, info: cls(v) if isinstance(v, str) else v,
            enum_schema,
        )

这个方法会让Pydantic始终将State视为枚举类型,序列化时保留实例,同时支持从字符串(如"Alaska")反序列化回枚举。

额外验证

若使用SQLAlchemy 2.0+,Mapped[State]可自动识别枚举类型,若需显式指定,可修改SQLAlchemy模型:

from sqlalchemy import Enum as SAEnum

class Item(Base):
    __tablename__ = "items"

    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str]
    state: Mapped[State] = mapped_column(SAEnum(State))

确保SQLAlchemy明确识别该字段为枚举类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:35:32