如何合并多个带独立环境文件的Pydantic Settings类并读取全部配置
问题描述
现有两个BaseSettings子类,分别从各自的环境文件加载配置,现在要合并成一个Settings类实现扁平命名空间,同时支持IDE自动补全,但当前代码只能读取最后一个父类的环境文件配置,前一个父类的配置只能取默认值。
原代码
import logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO, format='%(message)s') from pydantic import BaseModel from pydantic_settings import BaseSettings, SettingsConfigDict class DatabaseSettings(BaseSettings): model_config = SettingsConfigDict( env_prefix="APP_", env_file=".env.database", env_file_encoding="utf-8", extra="ignore", ) db_host: str = "localhost" class AuthSettings(BaseSettings): model_config = SettingsConfigDict( env_prefix="APP_", env_file=".env.auth", env_file_encoding="utf-8", extra="ignore", ) auth_secret_key: str = "change-me" class Settings(DatabaseSettings, AuthSettings): model_config = SettingsConfigDict( env_prefix='APP_', extra='ignore' ) pass settings = Settings() log.info(f"Settings: {settings}")
环境文件内容
# .env.database APP_DB_HOST=db.example.com
# .env.auth APP_AUTH_SECRET_KEY=secret-from-env-file
当前结果
Settings: auth_secret_key='secret-from-env-file' db_host='localhost'
期望结果
Settings: auth_secret_key='secret-from-env-file' db_host='db.example.com' # 注意db_host的值来自环境文件而非默认值"localhost"
解决方案
问题出在多继承BaseSettings时,父类的env_file配置会被后续父类覆盖,最终只有最后一个父类的环境文件被加载。要解决这个问题,只需在最终的Settings类中统一指定所有需要加载的环境文件,同时保留子类的其他配置规则:
- 移除子类中的
env_file配置项 - 在
Settings类的model_config中,将env_file设为包含所有环境文件路径的列表
修改后的完整代码
import logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO, format='%(message)s') from pydantic import BaseModel from pydantic_settings import BaseSettings, SettingsConfigDict class DatabaseSettings(BaseSettings): model_config = SettingsConfigDict( env_prefix="APP_", env_file_encoding="utf-8", extra="ignore", ) db_host: str = "localhost" class AuthSettings(BaseSettings): model_config = SettingsConfigDict( env_prefix="APP_", env_file_encoding="utf-8", extra="ignore", ) auth_secret_key: str = "change-me" class Settings(DatabaseSettings, AuthSettings): model_config = SettingsConfigDict( env_prefix='APP_', env_file=[".env.database", ".env.auth"], env_file_encoding="utf-8", extra='ignore' ) settings = Settings() log.info(f"Settings: {settings}")
关键说明
- Pydantic Settings的
env_file参数支持接收列表,会按顺序加载所有指定的环境文件,若出现重复变量,后面文件中的值会覆盖前面的 - 子类保留
env_prefix等配置,确保每个字段的环境变量解析规则保持不变 - 这种实现方式无需动态类创建或属性赋值,完全兼容IDE的自动补全和类型检查功能
运行结果
Settings: auth_secret_key='secret-from-env-file' db_host='db.example.com'
内容的提问来源于stack exchange,提问作者HanSooloo
相关产品推荐
相关产品推荐

