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

如何声明受运行时确定列表约束的Pydantic字段?

解决Pydantic v1.10运行时动态约束字段可选值的问题

错误原因

你遇到的TypeError: unhashable type: 'list'是因为Literal类型要求传入哈希可比较的字面量/常量,而你直接将运行时生成的列表conversion传入Literal,列表属于不可哈希类型,导致Pydantic无法生成对应的验证器。

解决方案

方法一:将动态列表转为元组,构建Literal类型

元组是哈希可比较类型,只需在类定义前将获取到的列表转为元组,再传入Literal即可,这种方式和status字段的约束逻辑完全一致,同时保留类型提示。

from typing import Literal, Tuple

from pydantic import BaseModel, Field

from connectors.snowflake.snowflake_connector import SnowflakeConnector

# 获取运行时可选值并转为元组
conversion_list = SnowflakeConnector().get_conversion()["conversion_name"].tolist()
conversion_tuple = tuple(conversion_list)

class MyModel(BaseModel):
    code: int = Field(alias="Code", frozen=True)
    status: Literal["Active", "Inactive"] = Field(alias="Status")
    conversion: Literal[conversion_tuple] = Field(alias="Conversion")

方法二:自定义验证器(更灵活)

如果需要动态更新可选值或添加复杂验证逻辑,可使用Pydantic的@validator装饰器自定义验证规则,检查输入值是否在允许的列表内。

from typing import Any

from pydantic import BaseModel, Field, validator

from connectors.snowflake.snowflake_connector import SnowflakeConnector

# 获取运行时允许的可选值列表
allowed_conversions = SnowflakeConnector().get_conversion()["conversion_name"].tolist()

class MyModel(BaseModel):
    code: int = Field(alias="Code", frozen=True)
    status: Literal["Active", "Inactive"] = Field(alias="Status")
    conversion: str = Field(alias="Conversion")

    @validator("conversion")
    def check_conversion_valid(cls, v: Any) -> Any:
        if v not in allowed_conversions:
            raise ValueError(f"conversion必须是以下值之一:{allowed_conversions}")
        return v

两种方法对比

  • 方法一:保留Literal的静态类型提示,IDE可识别可选值,验证逻辑由Pydantic自动处理,行为和status字段完全一致。
  • 方法二:支持动态更新可选值列表,可扩展复杂验证逻辑,但失去Literal的静态类型提示能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:04:54