让 Pydantic 设置在继承时读取带前缀和不带前缀的 .env 变量的正确方法是什么?

问题描述 投票:0回答:1

我有这个设置/配置设置,其想法是能够轻松地在开发、测试、生产等配置之间切换,并且我希望首先加载 BaseConfig 中的字段,无论配置类型如何,然后再加载要加载的适当前缀字段。 然而,无论我尝试什么,我都无法让它工作。

我的简化设置

from pydantic_settings import BaseSettings, SettingsConfigDict


class BaseConfig(BaseSettings):
    ENV_STATE: str
    SECRET_KEY: str

    model_config = SettingsConfigDict(
        env_file=".env",
        extra="ignore",
    )


class DevConfig(BaseConfig):
    DB_USERNAME: str
    DB_PASSWORD: str

    model_config = SettingsConfigDict(
        env_prefix="DEV_",
        extra="allow",
    )


def get_config(env_state: str) -> BaseConfig:
    configs = {"DEV": DevConfig}
    return configs[env_state]()


config = get_config("DEV")

print(config.ENV_STATE)
print(config.SECRET_KEY)
print(config.ALGORITHM)
print(config.DB_USERNAME)
print(config.DB_PASSWORD)

我的 .env 看起来像这样

ENV_STATE="DEV"
SECRET_KEY = "gj5490ghj4569gj"

DEV_DB_USERNAME = "username"
DEV_DB_PASSWORD = "pass123"

但是,当我运行代码时,出现此错误

pydantic_core._pydantic_core.ValidationError:DevConfig 的 2 个验证错误 ENV_STATE 必填字段 [type=missing, input_value={'DB_USERNAME': 'username...DB_PASSWORD': 'pass123'}, input_type=dict] 有关更多信息,请访问 https://errors.pydantic.dev/2.5/v/missing 密钥 必填字段 [type=missing, input_value={'DB_USERNAME': 'username...DB_PASSWORD': 'pass123'}, input_type=dict] 有关更多信息,请访问 https://errors.pydantic.dev/2.5/v/missing

所以它似乎只加载前缀字段,即使有 extra="allow",这很奇怪,因为如果我在 BaseConfig 的定义中为 ENV_STATE 和 SECRET_KEY 提供默认值,它就可以工作,所以从 BaseSettings 继承值没有问题,DevSettings 应该只构建在其之上,但它不想从 .env 文件中获取它们。

如何让它发挥作用?

python inheritance config pydantic dotenv
1个回答
0
投票

Pydantic 中的错误消息有点不清楚,但是,它们指向正确的方向。

ENV_STATE: str
SECRET_KEY: str
在您的配置中被定义为强制,但是,当您创建配置时,它们没有任何值
config = get_config("DEV")

要解决此问题,您必须以某种方式提供丢失的数据,无论是使用 .env 这样的配置文件还是在创建配置对象本身时,即

    configs = {"DEV": DevConfig}

    configs = {"DEV": DevConfig(ENV_STATE='dev', SECRET_KEY='secret')}

© www.soinside.com 2019 - 2024. All rights reserved.