为何pydantic_settings无法正确解析指定的dotenv文件?
可能的原因
1. 工作目录与文件路径不匹配
你的config.py位于app目录下,若运行程序时的工作目录不是myproject根目录,相对路径(如.local.env)会指向错误位置,导致Pydantic无法找到指定的env文件,可能通过其他自动加载逻辑回退到读取.env。
2. 环境变量优先级高于env文件
Pydantic Settings的变量优先级为:系统环境变量 > 命令行参数 > env文件变量 > 默认值。如果系统中已设置APP_ENV、APP_DB_URL等环境变量,env文件中的值会被直接覆盖,看起来像是程序只读取了.env。
3. 多次覆盖model_config且旧格式无效
你在代码中多次给model_config赋值,最后使用的旧格式class Config:在Pydantic Settings v2中已被废弃,完全不生效。此时若没有有效的model_config配置,程序可能通过第三方库(如python-dotenv)的逻辑加载了.env文件。
4. 第三方库自动加载了.env
若代码中使用了python-dotenv的load_dotenv()方法,该函数默认会加载根目录的.env,会覆盖Pydantic的配置。
解决方案
方案1:正确配置model_config(基于根目录运行)
确保在myproject根目录下运行程序(如执行uvicorn app.main:app),并使用v2格式的model_config指定env文件优先级:
# app/config.py from pydantic_settings import BaseSettings, SettingsConfigDict class EnvironmentSettings(BaseSettings): APP_ENV: str APP_DB_URL: str # .local.env 优先级高于 .env,相同变量取前者 model_config = SettingsConfigDict(env_file=(".local.env", ".env"))
方案2:基于文件路径动态定位env文件(不受工作目录影响)
通过__file__获取config.py的绝对路径,拼接根目录的env文件路径,确保无论在哪运行都能找到文件:
# app/config.py from pydantic_settings import BaseSettings, SettingsConfigDict import os # 获取myproject根目录路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class EnvironmentSettings(BaseSettings): APP_ENV: str APP_DB_URL: str model_config = SettingsConfigDict( env_file=( os.path.join(BASE_DIR, ".local.env"), os.path.join(BASE_DIR, ".env") ) )
方案3:检查并清除冲突的环境变量
运行以下命令检查是否存在相关环境变量:
# Windows echo %APP_ENV% echo %APP_DB_URL% # Linux/macOS echo $APP_ENV echo $APP_DB_URL
若输出对应值,说明环境变量已设置,可临时清除(如Windows执行set APP_ENV=,Linux执行unset APP_ENV),避免覆盖env文件内容。
方案4:排查第三方库的自动加载逻辑
检查代码中是否调用了python-dotenv的load_dotenv(),若有,可删除该调用,或指定加载目标文件:
from dotenv import load_dotenv # 仅加载指定的.env文件 load_dotenv(os.path.join(BASE_DIR, ".local.env"))
验证方法
添加打印代码确认加载结果:
settings = EnvironmentSettings() print(f"APP_ENV: {settings.APP_ENV}") print(f"配置的env文件路径: {settings.model_config.get('env_file')}")
内容的提问来源于stack exchange,提问作者Kalpadiptya Roy

