# fastapi-template（mysql 分支）

> 本分支为 **MySQL（SQLAlchemy 2.0 async + aiomysql + alembic）单后端**精简版。
> 双后端可切换版见 `main` 分支，MongoDB 版见 `mongodb` 分支。


开箱即用的 FastAPI 项目模板。**一条环境变量切换 MySQL / MongoDB**，业务代码零改动。

- MySQL：SQLAlchemy 2.0 async + aiomysql + Alembic 迁移
- MongoDB：Beanie ODM + Motor
- 工程化：uv 管理依赖、ruff lint、pytest 异步测试、Docker / compose 一键起

> 写给 AI Agent 的开发规范见 [AGENTS.md](./AGENTS.md)。
> FastAPI 通用最佳实践（原版文档）：[docs/BEST_PRACTICES_ZH.md](./docs/BEST_PRACTICES_ZH.md)

## 快速开始

```bash
# 1. 克隆后改个名
git clone https://git.code-lab.cn/Quentin/fastapi-template.git my-project && cd my-project

# 2. 配置：选数据库后端
cp .env.example .env
# 编辑 .env：DB_BACKEND=mongodb 或 mysql，填对应 DSN

# 3. 装依赖（uv）
uv sync

# 4. 起数据库（或直接用现成的）
docker compose up -d mongo     # MongoDB
docker compose up -d mysql     # MySQL

# 5. 跑！
uv run uvicorn src.main:app --reload
```

打开 http://127.0.0.1:8000/docs 看交互式 API 文档，
`GET /health` 会返回当前生效的 `db_backend`。

## 切库说明

| | MySQL | MongoDB |
|---|---|---|
| 开关 | `DB_BACKEND=mysql` | `DB_BACKEND=mongodb` |
| 连接 | `MYSQL_DSN=mysql+aiomysql://user:pass@host:3306/db` | `MONGO_DSN` + `MONGO_DB` |
| 模型 | `src/{domain}/mysql.py`（ORM） | `src/{domain}/mongo.py`（Document） |
| 迁移 | `alembic revision --autogenerate` + `upgrade head` | 不需要（beanie 自动建索引） |

router/service 只依赖 `ItemRepo` 协议（见 `src/items/dependencies.py`），
两个后端实现同一套接口，`.env` 改一行即切换。

## 项目结构

```
├── src/
│   ├── main.py            # app 工厂 + lifespan（按后端初始化 DB）
│   ├── config.py          # pydantic-settings 全局配置
│   ├── database.py        # MySQL engine/session（仅 mysql 模式使用）
│   ├── mongo.py           # beanie 初始化（仅 mongodb 模式使用）
│   ├── exceptions.py      # 全局异常 + 统一错误响应
│   └── items/             # 示例域（新增域照抄这个目录）
│       ├── router.py      # 路由：只依赖 ItemRepo 协议
│       ├── schemas.py     # Pydantic 契约（与 DB 无关）
│       ├── dependencies.py# 按 DB_BACKEND 选仓储实现
│       ├── mysql.py       # MySQL 模型 + 仓储
│       └── mongo.py       # MongoDB Document + 仓储
├── alembic/               # MySQL 迁移
├── tests/                 # pytest + httpx ASGITransport
├── Dockerfile
└── docker-compose.yml     # app + mysql + mongo
```

## 常用命令

```bash
uv run pytest                # 测试（默认 mongodb 后端，库名 app_test）
uv run ruff check --fix .    # lint + 自动修
uv run alembic revision --autogenerate -m "msg"   # 生成 MySQL 迁移
uv run alembic upgrade head                       # 执行迁移
docker compose up -d --build # 整套起
```

## 新增一个业务域

照抄 `src/items/` 为 `src/{domain}/`，然后：

1. `mongo.py` 里写 Document，并在 `src/mongo.py` 的 `_collect_documents()` 登记
2. `mysql.py` 里写 ORM 模型，并在 `alembic/env.py` import 保证 metadata 可见
3. `main.py` 里 `include_router`

详细规范（结构、命名、依赖注入、异步纪律、Git 提交）都在 [AGENTS.md](./AGENTS.md)。
