db867dcbe5
Deploy to Staging / deploy (push) Has been cancelled
Conflict detector / main (push) Has been cancelled
Lint Backend / lint-backend (push) Has been cancelled
Playwright Tests / changes (push) Has been cancelled
Test Backend / test-backend (push) Has been cancelled
Test Docker Compose / test-docker-compose (push) Has been cancelled
Playwright Tests / test-playwright (1, 4) (push) Has been cancelled
Playwright Tests / test-playwright (2, 4) (push) Has been cancelled
Playwright Tests / test-playwright (3, 4) (push) Has been cancelled
Playwright Tests / test-playwright (4, 4) (push) Has been cancelled
Playwright Tests / merge-playwright-reports (push) Has been cancelled
Playwright Tests / alls-green-playwright (push) Has been cancelled
Issue Manager / issue-manager (push) Has been cancelled
183 lines
6.7 KiB
Markdown
183 lines
6.7 KiB
Markdown
# FastAPI 项目 - 后端(Backend)
|
||
|
||
## 前置要求
|
||
|
||
* 已安装 [Docker](https://www.docker.com/)。
|
||
* 已安装 [uv](https://docs.astral.sh/uv/),用于管理 Python 包与虚拟环境。
|
||
|
||
## 使用 Docker Compose
|
||
|
||
按照 [../development.md](../development.md) 中的说明,使用 Docker Compose 启动本地开发环境。
|
||
|
||
## 一般工作流
|
||
|
||
本项目默认使用 [uv](https://docs.astral.sh/uv/) 管理依赖,请先安装它。
|
||
|
||
在 `./backend/` 目录下安装所有依赖:
|
||
|
||
```console
|
||
$ uv sync
|
||
```
|
||
|
||
然后激活虚拟环境:
|
||
|
||
```console
|
||
$ source .venv/bin/activate
|
||
```
|
||
|
||
请确保你的编辑器使用的是该虚拟环境中的 Python 解释器:`backend/.venv/bin/python`。
|
||
|
||
你可以在 `./backend/app/models.py` 中修改或新增 SQLModel 模型(数据表结构),在 `./backend/app/api/` 中添加 API 路由,在 `./backend/app/crud.py` 中添加 / 修改 CRUD(创建、读取、更新、删除)工具函数。
|
||
|
||
## VS Code
|
||
|
||
项目中已经包含了 VS Code 的调试配置,你可以直接使用断点、单步调试、查看变量等功能来运行后端。
|
||
|
||
测试相关配置也已就绪,可以通过 VS Code 的 Python 测试面板直接运行测试。
|
||
|
||
## Docker Compose 覆盖配置
|
||
|
||
开发阶段,你可以在 `docker-compose.override.yml` 中修改仅作用于本地开发环境的 Docker Compose 配置。
|
||
|
||
这些改动只影响本地开发环境,不会影响生产环境。因此你可以在这里加入一些“临时”设置来提升本地开发效率。
|
||
|
||
例如:后端代码目录会以 volume 形式挂载进容器,你在本机修改代码后会实时同步到容器中,无需重新构建镜像即可看到效果。生产环境则应该基于最新代码重新构建镜像,而不是使用挂载的源码。
|
||
|
||
配置中还包含一个覆盖命令,将默认的 `fastapi run` 改为 `fastapi run --reload`。它只启动一个进程(适合开发环境),并在检测到代码变更时自动重载。注意,如果保存了含语法错误的 Python 文件,进程会直接退出、容器也会停止。修复错误后,可以再次运行:
|
||
|
||
```console
|
||
$ docker compose watch
|
||
```
|
||
|
||
文件中还提供了一个被注释掉的 `command` 覆盖项,你可以取消注释它并注释掉默认命令。该命令会让后端容器运行一个“空转”的进程,只是保持容器存活,方便你进入容器内部执行命令,例如打开 Python 交互解释器测试依赖,或手动启动支持热重载的开发服务器。
|
||
|
||
如果你想通过 `bash` 进入容器,可以先启动整个 stack:
|
||
|
||
```console
|
||
$ docker compose watch
|
||
```
|
||
|
||
然后在另一个终端中执行:
|
||
|
||
```console
|
||
$ docker compose exec backend bash
|
||
```
|
||
|
||
你会看到类似输出:
|
||
|
||
```console
|
||
root@7f2607af31c3:/app#
|
||
```
|
||
|
||
这说明你已经以 `root` 用户进入了容器中的 `/app` 目录,该目录下还有一个 `app` 子目录,即你的后端代码在容器中的位置:`/app/app`。
|
||
|
||
在这里可以运行支持热重载的开发服务器:
|
||
|
||
```console
|
||
$ fastapi run --reload app/main.py
|
||
```
|
||
|
||
终端看起来会类似:
|
||
|
||
```console
|
||
root@7f2607af31c3:/app# fastapi run --reload app/main.py
|
||
```
|
||
|
||
然后按回车即可启动,它会在检测到代码变化时自动重载。
|
||
|
||
如果碰到的不是代码变更而是语法错误,进程会直接退出。不过因为容器还在且你仍在 Bash 会话中,修复错误后按方向键上翻历史命令并回车即可快速重启。
|
||
|
||
正是因为这一点,让“容器空转 + Bash 中手动启动热重载服务”的方式在开发中非常实用。
|
||
|
||
## 后端测试
|
||
|
||
运行后端测试:
|
||
|
||
```console
|
||
$ bash ./scripts/test.sh
|
||
```
|
||
|
||
测试使用 Pytest,测试文件位于 `./backend/tests/`,你可以在其中新增或修改测试。
|
||
|
||
如果你使用 GitHub Actions,推送代码后测试会自动运行。
|
||
|
||
### 在已运行的 stack 中执行测试
|
||
|
||
如果 Docker Compose 已经启动,只想在当前 stack 中运行测试,可以使用:
|
||
|
||
```bash
|
||
docker compose exec backend bash scripts/tests-start.sh
|
||
```
|
||
|
||
`/app/scripts/tests-start.sh` 脚本会在确认依赖服务已就绪后调用 `pytest`。如果需要给 `pytest` 传额外参数,可以直接附加在命令后面,它们会被转发给 `pytest`。
|
||
|
||
例如,遇到第一个错误就停止:
|
||
|
||
```bash
|
||
docker compose exec backend bash scripts/tests-start.sh -x
|
||
```
|
||
|
||
### 测试覆盖率
|
||
|
||
测试运行后会生成 `htmlcov/index.html` 文件,可在浏览器中打开查看覆盖率报告。
|
||
|
||
## 数据库迁移(Migrations)
|
||
|
||
本地开发时,应用代码目录以 volume 形式挂载到容器中,因此可以在容器内使用 `alembic` 命令生成迁移文件,这些文件会直接写入你的项目目录,方便你提交到 git 仓库。
|
||
|
||
每次修改模型后,请确保:
|
||
|
||
1. 创建新的迁移“revision”,描述本次模型变更;
|
||
2. 使用该 revision 升级数据库。
|
||
|
||
否则数据库表结构不会更新,应用就会报错。
|
||
|
||
基本流程如下:
|
||
|
||
* 在后端容器中启动交互会话:
|
||
|
||
```console
|
||
$ docker compose exec backend bash
|
||
```
|
||
|
||
* `alembic` 已配置好从 `./backend/app/models.py` 导入 SQLModel 模型。
|
||
|
||
* 修改模型(例如新增字段)后,在容器内创建迁移 revision,例如:
|
||
|
||
```console
|
||
$ alembic revision --autogenerate -m "Add column last_name to User model"
|
||
```
|
||
|
||
* 将 Alembic 目录中生成的 Python 迁移文件提交到 git。
|
||
|
||
* 创建完 revision 后,在数据库中执行迁移(真正修改数据库结构):
|
||
|
||
```console
|
||
$ alembic upgrade head
|
||
```
|
||
|
||
如果你完全不想使用迁移,可以在 `./backend/app/core/db.py` 中取消注释以 `SQLModel.metadata.create_all(engine)` 结尾的代码:
|
||
|
||
```python
|
||
SQLModel.metadata.create_all(engine)
|
||
```
|
||
|
||
同时在 `scripts/prestart.sh` 中注释掉包含以下内容的那一行:
|
||
|
||
```console
|
||
$ alembic upgrade head
|
||
```
|
||
|
||
如果你不想从默认模型开始,而是从零开始定义自己的模型,并且不希望有任何已有迁移,可以删除 `./backend/app/alembic/versions/` 下的所有迁移文件(`.py`),然后按上述步骤创建第一条迁移。
|
||
|
||
## 邮件模板
|
||
|
||
邮件模板位于 `./backend/app/email-templates/` 目录,其中:
|
||
|
||
- `src`:存放源模板(`.mjml` 文件等),用于生成最终 HTML 模板;
|
||
- `build`:存放构建后的 HTML 邮件模板,实际由应用使用。
|
||
|
||
继续之前,请先在 VS Code 中安装 [MJML 扩展](https://marketplace.visualstudio.com/items?itemName=attilabuti.vscode-mjml)。
|
||
|
||
安装完成后,你可以在 `src` 目录中创建新的邮件模板。创建好 `.mjml` 文件并在编辑器中打开后,按 `Ctrl+Shift+P` 打开命令面板,搜索 `MJML: Export to HTML`。该命令会将 `.mjml` 文件转换为 `.html` 文件,然后你可以将其保存到 `build` 目录中供应用使用。
|