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

如何合并多个带独立环境文件的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 23:42:45