如何在Pydantic模型中从.env文件将字符串转为字典类型变量
解决Pydantic BaseSettings读取.env中字典字符串的类型转换问题
问题重现
.env文件内容
# .env a="a" b="b" c='{"s": 1}'
注意:实际使用时需移除JSON中的
...占位符,保证字符串为合法JSON格式
原代码实现
from pydantic import BaseModel, BaseSettings class C_MODEL(BaseModel): s: int class Settings(BaseSettings): class Config: env_file = '.env' env_file_encoding = 'utf-8' a: str b: str = "default" c: C_MODEL = C_MODEL() settings: Settings = Settings()
报错信息
pydantic.error_wrappers.ValidationError: 1 validation errors for C_MODEL
问题核心:Pydantic默认无法直接将.env中的JSON字符串自动转换为C_MODEL实例,需要手动处理字符串到字典的解析。
解决方案
方案1:使用字段验证器(Validator)
通过自定义字段验证器,将JSON字符串解析为字典后再实例化C_MODEL,兼容Pydantic v1和v2(注意装饰器差异)。
Pydantic v1版本代码
from pydantic import BaseModel, BaseSettings, validator import json class C_MODEL(BaseModel): s: int class Settings(BaseSettings): class Config: env_file = '.env' env_file_encoding = 'utf-8' a: str b: str = "default" c: C_MODEL = C_MODEL() @validator('c') def parse_c_from_json(cls, value): # 如果传入的是字符串,尝试解析为JSON if isinstance(value, str): try: json_dict = json.loads(value) return C_MODEL(**json_dict) except json.JSONDecodeError: raise ValueError("环境变量c必须是合法的JSON字符串") # 如果已经是C_MODEL实例或字典,直接返回 return value settings = Settings() print(settings.c.s) # 输出: 1
Pydantic v2版本代码
v2中validator替换为field_validator,并需指定mode="before"确保在类型转换前执行:
from pydantic import BaseModel, BaseSettings, field_validator import json class C_MODEL(BaseModel): s: int class Settings(BaseSettings): model_config = {"env_file": ".env", "env_file_encoding": "utf-8"} a: str b: str = "default" c: C_MODEL = C_MODEL() @field_validator('c', mode="before") def parse_c_from_json(cls, value): if isinstance(value, str): try: json_dict = json.loads(value) return C_MODEL(**json_dict) except json.JSONDecodeError: raise ValueError("环境变量c必须是合法的JSON字符串") return value settings = Settings() print(settings.c.s) # 输出: 1
方案2:使用Pydantic Json类型
直接使用Json类型声明字段,让Pydantic自动处理JSON字符串到目标模型的转换(适用于Pydantic v2,v1需安装pydantic[json]扩展)。
from pydantic import BaseModel, BaseSettings, Json class C_MODEL(BaseModel): s: int class Settings(BaseSettings): model_config = {"env_file": ".env", "env_file_encoding": "utf-8"} a: str b: str = "default" c: Json[C_MODEL] = C_MODEL() settings = Settings() print(settings.c.s) # 输出: 1
内容的提问来源于stack exchange,提问作者Industry666
相关产品推荐
相关产品推荐

