Add design document for migrating from .env to YAML configuration using pydantic-yaml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.8 KiB
4.8 KiB
YAML 配置系统设计文档
日期: 2026-05-12 作者: Claude 状态: 已批准
概述
将 FastAPI 服务的配置管理从 .env 文件迁移到 YAML 格式,提升配置可读性和团队维护性。
需求背景
- 驱动因素: 更好的可读性,便于团队维护
- 环境支持: 单文件配置,无需多环境切换
- 实现方案: 使用
pydantic-yaml保留类型验证
文件结构
services/fastapi/
├── config/
│ ├── __init__.py
│ ├── settings.yaml # 配置文件
│ └── settings.py # 配置类定义
├── app/
│ ├── core/
│ │ └── database.py # 使用配置
│ └── ...
├── tests/
│ ├── fixtures/
│ │ └── test_config.yaml
│ └── ...
└── requirements.txt
配置文件格式
config/settings.yaml
# 数据库配置
database:
sql_server:
host: 192.168.110.114
port: 1433
database: CompanyDB
username: peng
password: Cqbld123456.
driver: "{ODBC Driver 18 for SQL Server}"
trust_server_certificate: yes
配置类设计
config/settings.py
from pathlib import Path
from sqlalchemy.engine import URL
from pydantic import BaseModel
from pydantic_yaml import YamlModel
class SqlServerConfig(BaseModel):
"""SQL Server 连接配置"""
host: str
port: int = 1433
database: str
username: str
password: str
driver: str = "{ODBC Driver 18 for SQL Server}"
trust_server_certificate: str = "yes"
class Settings(YamlModel):
"""应用配置"""
database: SqlServerConfig
@property
def database_url(self) -> URL:
"""构建数据库连接 URL"""
conf = self.database.sql_server
return URL.create(
"mssql+pyodbc",
username=conf.username,
password=conf.password,
host=conf.host,
port=conf.port,
database=conf.database,
query={
"driver": conf.driver.strip("{}"),
"TrustServerCertificate": conf.trust_server_certificate,
},
)
def load_settings(config_path: str = "config/settings.yaml") -> Settings:
"""加载 YAML 配置文件"""
path = Path(config_path)
if not path.exists():
raise FileNotFoundError(
f"配置文件不存在: {config_path}\n"
f"请确保文件存在于项目根目录或指定正确路径"
)
return Settings.parse_yaml_file(path)
# 全局配置单例
settings = load_settings()
config/init.py
from config.settings import settings, Settings, load_settings
__all__ = ["settings", "Settings", "load_settings"]
依赖变更
requirements.txt 新增
pydantic-yaml>=0.12.0
pyyaml>=6.0
可选移除
python-dotenv # 如无其他用途
导入路径变更
| 旧导入 | 新导入 |
|---|---|
from app.core.config import settings |
from config.settings import settings |
错误处理
应用启动时验证
# app/main.py
import sys
from config.settings import load_settings
try:
settings = load_settings()
except FileNotFoundError as e:
print(f"配置文件错误: {e}")
sys.exit(1)
except Exception as e:
print(f"加载配置失败: {e}")
sys.exit(1)
测试策略
单元测试
# tests/test_config.py
import pytest
from config.settings import load_settings
def test_load_settings_success():
settings = load_settings("tests/fixtures/test_config.yaml")
assert settings.database.sql_server.port == 1433
def test_load_settings_file_not_found():
with pytest.raises(FileNotFoundError):
load_settings("nonexistent.yaml")
def test_database_url_property():
settings = load_settings("tests/fixtures/test_config.yaml")
url = settings.database_url
assert "mssql+pyodbc" in url
测试配置文件
# tests/fixtures/test_config.yaml
database:
sql_server:
host: localhost
port: 1433
database: TestDB
username: test_user
password: test_pass
driver: "{ODBC Driver 18 for SQL Server}"
trust_server_certificate: yes
迁移步骤
- 新增依赖 - 更新 requirements.txt
- 创建模块 - 创建 config/ 目录和相关文件
- 更新导入 - 替换所有
from app.core.config import settings - 更新测试 - 创建测试配置和夹具
- 清理旧代码 - 删除旧配置文件
- 验证 - 运行测试和启动应用
后续扩展
如需支持多环境,可通过以下方式扩展:
# config/settings.base.yaml (基础配置)
database:
sql_server:
driver: "{ODBC Driver 18 for SQL Server}"
trust_server_certificate: yes
# config/settings.dev.yaml (开发环境覆盖)
database:
sql_server:
host: localhost
database: DevDB