📅 今日知识点
-
核心主题:上一篇文章我们讲解了如何使用pydantic做配置管理,本期文章展示在使用Pydantic管理应用配置时,如何进行多环境配置切换
-
适用场景:应用的多环境部署
-
一句话总结:通过Pydantic实现环境隔离的配置管理,一套代码适配多种部署环境
🧩 核心原理(简化版)
-
基于环境变量动态选择配置类,实现配置的环境隔离
-
核心逻辑:通过工厂函数,根据ENVIRONMENT环境变量返回对应的配置实例
-
核心价值:避免硬编码环境判断,支持配置热重载,提升部署灵活性
1. 多环境配置类
import os
from enum import Enum
from typing import Union
from pydantic import field_validator
from pydantic_settings import BaseSettings
class Environment(str, Enum):
"""环境枚举"""
DEVELOPMENT = "dev"
STAGING = "staging"
PRODUCTION = "prod"
class EnvSettings(BaseSettings):
"""环境相关配置"""
environment: Environment = Environment.DEVELOPMENT
secret_key: str = "" # 提供默认空值,避免必填验证错误
@field_validator('environment', mode="before")
@classmethod
def validate_environment(cls, v):
if isinstance(v, str):
return Environment(v.lower())
return v
class DevSettings(EnvSettings):
def __init__(self, _env_file: str = ".env.prod"):
super().__init__()
self.__env_file = _env_file
"""开发环境配置"""
debug: bool = True
log_level: str = "DEBUG"
model_config = {
"env_file": ".env.dev",
"env_file_encoding": "utf-8",
"case_sensitive": False,
"extra": "ignore"
}
class ProdSettings(EnvSettings):
def __init__(self, _env_file: str = ".env.prod"):
super().__init__()
self.__env_file = _env_file
"""生产环境配置"""
debug: bool = False
log_level: str = "WARNING"
model_config = {
"env_file": ".env.prod",
"env_file_encoding": "utf-8",
"case_sensitive": False,
"extra": "ignore"
}
2. 环境配置的工场函数
# 环境工厂函数
def get_settings() -> Union[DevSettings, ProdSettings]:
"""根据环境变量返回对应配置"""
env = os.getenv("ENVIRONMENT", "dev").lower()
if env == "prod":
return ProdSettings(_env_file=".env.prod")
else:
return DevSettings(_env_file=".env.dev")
3. 测试
if __name__ == "__main__":
settings = get_settings()
print(f"当前环境: {settings.environment}")
print(f"调试模式: {settings.debug}")
print(f"Secret Key: {settings.secret_key}")
测试结果:
当前环境: Environment.PRODUCTION
调试模式: False
Secret Key: 78910
4. 核心要点
# 1. 环境枚举:使用Enum确保环境值的有效性
class Environment(str, Enum):
"""环境枚举"""
DEVELOPMENT = "dev"
STAGING = "staging"
PRODUCTION = "prod"
# 2. 配置继承:不同环境配置继承基础配置
class DevSettings(BaseSettings):
debug: bool = True
# 3. 工厂模式:根据环境变量返回配置实例
def get_settings() -> Union[DevSettings, ProdSettings]:
"""根据环境变量返回对应配置"""
env = os.getenv("ENVIRONMENT", "dev").lower()
if env == "prod":
return ProdSettings(_env_file=".env.prod")
else:
return DevSettings(_env_file=".env.dev")
⚠️ 避坑指南(简洁重点)
核心坑:环境变量未设置导致的默认行为
# ❌ 问题:未设置ENVIRONMENT时总是返回开发配置
env = os.getenv("ENVIRONMENT", "dev") # 默认值可能导致生产环境误用开发配置
# ✅ 最佳实践:生产环境必须显式设置
env = os.environ["ENVIRONMENT"]
✅ 今日总结
- 多环境配置管理核心是:环境隔离和通过工厂函数实现配置的灵活管理
- 关键要点:环境枚举、配置继承、环境文件分离、工厂模式、环境变量优先