docs: add YAML configuration design document
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>
This commit is contained in:
223
docs/plans/2026-05-12-yaml-configuration-design.md
Normal file
223
docs/plans/2026-05-12-yaml-configuration-design.md
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
|
||||||
|
```python
|
||||||
|
from config.settings import settings, Settings, load_settings
|
||||||
|
|
||||||
|
__all__ = ["settings", "Settings", "load_settings"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 依赖变更
|
||||||
|
|
||||||
|
### requirements.txt 新增
|
||||||
|
|
||||||
|
```txt
|
||||||
|
pydantic-yaml>=0.12.0
|
||||||
|
pyyaml>=6.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 可选移除
|
||||||
|
|
||||||
|
```txt
|
||||||
|
python-dotenv # 如无其他用途
|
||||||
|
```
|
||||||
|
|
||||||
|
## 导入路径变更
|
||||||
|
|
||||||
|
| 旧导入 | 新导入 |
|
||||||
|
|--------|--------|
|
||||||
|
| `from app.core.config import settings` | `from config.settings import settings` |
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
### 应用启动时验证
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试策略
|
||||||
|
|
||||||
|
### 单元测试
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试配置文件
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 迁移步骤
|
||||||
|
|
||||||
|
1. **新增依赖** - 更新 requirements.txt
|
||||||
|
2. **创建模块** - 创建 config/ 目录和相关文件
|
||||||
|
3. **更新导入** - 替换所有 `from app.core.config import settings`
|
||||||
|
4. **更新测试** - 创建测试配置和夹具
|
||||||
|
5. **清理旧代码** - 删除旧配置文件
|
||||||
|
6. **验证** - 运行测试和启动应用
|
||||||
|
|
||||||
|
## 后续扩展
|
||||||
|
|
||||||
|
如需支持多环境,可通过以下方式扩展:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 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
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user