Files
fastAPI/docs/plans/2026-05-12-yaml-configuration-design.md
Misaka_Company 01423ccccc 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>
2026-05-12 09:25:46 +08:00

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

迁移步骤

  1. 新增依赖 - 更新 requirements.txt
  2. 创建模块 - 创建 config/ 目录和相关文件
  3. 更新导入 - 替换所有 from app.core.config import settings
  4. 更新测试 - 创建测试配置和夹具
  5. 清理旧代码 - 删除旧配置文件
  6. 验证 - 运行测试和启动应用

后续扩展

如需支持多环境,可通过以下方式扩展:

# 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