diff --git a/docs/task/7-实现-sqlite-初始化与-v1-迁移.md b/docs/task/7-实现-sqlite-初始化与-v1-迁移.md new file mode 100644 index 0000000..698be10 --- /dev/null +++ b/docs/task/7-实现-sqlite-初始化与-v1-迁移.md @@ -0,0 +1,65 @@ +# 7 实现 SQLite 初始化与 v1 迁移 + +- 类型:需求 +- 父级大工单:#1 +- 所属 MVP / 版本:#2 / MVP +- 状态:已完成 +- 日期:2026-08-06 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/7 + +## 背景与目标 + +Client 原来没有 SQLite 初始化代码,无法创建本地任务数据库或管理数据库版本。本任务建立简单、可重复执行的 v1 初始化,为后续任务数据模型和 Repository 提供基础。 + +## 最终方案 + +- 使用 Python 内置 `sqlite3`,不增加 ORM 或测试依赖。 +- 代码使用 `client/src` 扁平文件结构,测试统一放在 `client/test`。 +- `db.py` 负责数据目录、默认数据库路径、连接参数和迁移入口。 +- `db_schema.py` 集中保存按版本排列的 SQL,初始版本为 1。 +- v1 创建 `pdd_tasks`、`task_runs`、`outbox_events` 和 `app_settings`,字段、约束及索引与数据模型基线一致。 +- 每个连接启用外键、WAL、5000 ms busy timeout,并使用 `sqlite3.Row` 返回查询行。 +- 迁移在事务中逐版本执行;数据库版本高于程序支持版本时明确报错,不降级、不删除旧库。 +- 测试使用 `TemporaryDirectory`,不会创建或修改真实的 `client/data/client.db`。 + +## 改了哪些 + +- `client/src/db.py`:新增数据目录、数据库连接、迁移和初始化函数。 +- `client/src/db_schema.py`:新增 v1 表结构、约束、索引和迁移清单。 +- `client/test/test_db.py`:新增 SQLite 初始化单元测试。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 自定义路径首次初始化创建父目录和数据库文件 | 通过 | +| v1 创建四张表和规定索引 | 通过 | +| `PRAGMA user_version` 为 1 | 通过 | +| 重复初始化不报错且保留已有数据 | 通过 | +| 新连接启用外键、WAL 和 5000 ms busy timeout | 通过 | +| 任务类型、状态、金额和数量 CHECK 约束生效 | 通过 | +| 执行记录与 Outbox 外键约束生效 | 通过 | +| 高于支持版本的数据库被明确拒绝 | 通过 | +| 测试只使用临时数据库 | 通过 | +| 语法检查、unittest 和差异检查通过 | 通过 | + +## 测试 + +- 执行的命令: + + ```powershell + C:/Python310/python.exe -m py_compile src/db.py src/db_schema.py test/test_db.py + C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" -v + ``` + +- 结果:6 个测试全部通过,输出 `Ran 6 tests ... OK`;`git diff --check` 通过。 +- **没验证到的部分**:没有初始化真实的 `client/data/client.db`;没有进行多线程并发写入、断电恢复、旧版本升级或打包后路径测试;Repository、UI 和任务流程尚未接入数据库。 + +## 遗留问题 + +- 下一单元任务定义 Python 任务数据模型和 Repository。 +- 后续打包任务验证 exe 旁 `data/` 路径和历史数据库升级。 + +## 相关提交 + +- `69f0812` 实现 SQLite 初始化与 v1 迁移