# Location Recorder 本文档说明 `location recorder` 在 Python 项目中的当前数据库接管策略,以及 legacy SQLite 接管 runbook。 ## Legacy 事实基线 当前 legacy SQLite 中 `location` 表的真实 schema 为: ```sql CREATE TABLE location ( person TEXT NOT NULL, datetime TEXT NOT NULL, latitude REAL NOT NULL, longitude REAL NOT NULL, altitude REAL, PRIMARY KEY (person, datetime) ); ``` 历史上 legacy Go 实现使用: ```sql PRAGMA user_version = 2; ``` 这代表旧系统曾依赖 `user_version` 管理 location 数据库版本,但这不再是 Python 项目的长期 migration 机制。 ## 当前策略 当前采用的最小必要接管方案是: 1. 把上述 `location` schema 视为 Alembic baseline 2. 新数据库通过 Alembic `upgrade head` 初始化 3. 已有 legacy SQLite 数据库,只要确认 schema 与 baseline 一致,就通过 `alembic stamp` 接管 4. 未来不再以 `PRAGMA user_version` 作为主 migration 机制 当前 baseline revision 是: - `20260419_01_location_baseline` 当前提供的最小脚本入口是: ```bash python scripts/location_db_adopt.py ``` 如果你更喜欢模块方式运行,也可以用: ```bash python -m scripts.location_db_adopt ``` 它只针对 `LOCATION_DATABASE_URL` 工作,并且遵守保守接管原则: - 本地已有 DB 文件:先校验,再接管 - 本地没有 DB 文件:按新库初始化 - 任一校验不通过:立即报错并停止 ## 新数据库初始化 如果本地不存在 `LOCATION_DATABASE_URL` 指向的 DB 文件: - 脚本会先创建父目录 - 然后执行 Alembic `upgrade head` - 最终建立 `location` 表与 `alembic_version` 表 手工执行时也等价于: ```bash alembic upgrade head ``` 这会创建与 legacy 相同的 `location` 表结构,并在库中建立 Alembic revision 记录。 ## 旧数据库接管 对于已经存在的 legacy SQLite 数据库: 1. 先确认 DB 文件存在 2. 读取当前 DB 中 `location` 表的实际 schema 3. 与 baseline schema 做严格比对 4. 再检查 `PRAGMA user_version` 5. 只有 schema 匹配且 `user_version = 2` 时,才执行 Alembic `stamp` 6. 接管完成后,后续 migration 才交给 Alembic 管理 示例: ```bash LOCATION_DATABASE_URL=sqlite:///./data/locationRecorder.db alembic stamp 20260419_01_location_baseline ``` 或直接执行脚本: ```bash LOCATION_DATABASE_URL=sqlite:///./data/locationRecorder.db python scripts/location_db_adopt.py ``` 这样做的含义是: - 告诉 Alembic:这个数据库已经处于 baseline 结构 - 不修改已有 `location` 表数据 - 后续 migration 由 Alembic 接管 ## Fail Closed 原则 当前策略是保守接管,不做未知 legacy 状态的自动修复。 如果出现以下任一情况,脚本会直接报错并停止: - 找不到 `location` 表 - `location` 表 schema 与 baseline 不一致 - `PRAGMA user_version` 不等于 `2` - 目标 DB 不是 SQLite URL 当前不会尝试: - 自动修表 - 自动调整 `user_version` - 自动推断未知 legacy 状态 如果发生这些情况,应先人工确认数据库状态,再决定是否需要单独迁移或修复。 ## 关于 `data/locationRecorder.db` 你本地放在 `data/locationRecorder.db` 的 legacy 样本库,可以用于: - 人工核对 schema - 手动验证 `stamp` 接管流程 - 做开发时的兼容性确认 但当前代码不应硬依赖这个文件存在。 ## 测试样本的安全使用方式 如果要用 legacy SQLite 样本做测试或验证,应遵守: 1. 不直接在原始样本文件上跑测试 2. 先复制到临时路径 3. 所有 `stamp`、写入、实验性 migration 都只针对副本执行 自动化测试里当前采用的方式是: - 构造一个“legacy 风格”的临时 SQLite 文件 - 建出同样的 `location` 表 - 设置 `PRAGMA user_version = 2` - 再执行接管脚本中的 adopt 逻辑 同时也覆盖: - DB 文件不存在时的新库初始化路径 - schema 不匹配时的失败路径 - `user_version` 不匹配时的失败路径 这样可以验证接管路径,同时不污染真实样本库。