Files
ai_site/database_fastapi修改意见.md
2026-07-31 10:19:22 +08:00

108 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# database_fastapi 修改意见
> 针对文件:`E:\project\yh_one\new_project\yuhengyihao_client\yxd\app_fastapi\database_fastapi.py`
> 背景:需要与线上主库强一致;断网可记日志,恢复后合并回放至线上;主写在线上。
> 对照能力:宇信达智建平台 `dbsync` 出站队列 / 冲突 / 对账(见 `ai建站/docs/数据同步-中间件.md`)。
---
## 落地状态(已实现)
| 项 | 状态 | 位置 |
|----|------|------|
| 统一写网关 `apply_write` | ✅ | `db_write_gateway.py` |
| 写接口收口 | ✅ | insert / update / update/id / delete / sql(DML) |
| 库绑定防串库 | ✅ | `sync_binding.py``cache/db_bindings/bindings.json` |
| 配置 | ✅ | `sync_config.py`(环境变量) |
| 断网 pending | ✅ | 复用 `QueueDatabaseManager`,库名默认 `sync_pending` |
| 手动回放 | ✅ | `POST /database/sync/replay` |
| 绑定/状态 API | ✅ | `/database/sync/*` |
| 后台自动回放 | ✅ 可选 | `sync_replay_worker.py`,需 `YXD_SYNC_REPLAY_WORKER=1` |
| DDL / 批量 import 收口 | ⏳ 未做 | 仍可直写本地;后续按需收口 |
| 冲突队列 API | ⏳ 未做 | 回放失败即停保序,暂无独立 conflicts 列表 |
**默认安全**`YXD_SYNC_MODE` 未配且无 `YXD_ONLINE_API_BASE` 时为 **`local_only`**(只写本地,仍会 ensure 绑定信息)。
配了 `YXD_ONLINE_API_BASE` 且未显式写 `YXD_SYNC_MODE` 时自动升为 **`online_primary`**。
### 环境变量
| 变量 | 说明 | 默认 |
|------|------|------|
| `YXD_SYNC_MODE` | `local_only` \| `online_primary` | `local_only`(有 ONLINE_BASE 且未设 mode 则升 primary |
| `YXD_ONLINE_API_BASE` | 线上 API 根,如 `https://api.example.com` | 空 |
| `YXD_ONLINE_TIMEOUT_SEC` | 线上写超时 | `8` |
| `YXD_OFFLINE_POLICY` | `pending_log` \| `reject` | `pending_log` |
| `YXD_SYNC_ENFORCE_BINDING` | 是否强制已绑定 | `true` |
| `YXD_SYNC_AUTO_ENSURE_BINDING` | 写时自动 ensure | `true` |
| `YXD_SYNC_PENDING_QUEUE` | pending 队列库名 | `sync_pending` |
| `YXD_ONLINE_TOKEN_HEADER` | 透传 token 头 | `Authorization` |
| `YXD_SYNC_REPLAY_WORKER` | 启后台回放 | 关 |
| `YXD_SYNC_REPLAY_INTERVAL_SEC` | 回放间隔秒 | `30` |
### 新增/改动文件
```text
yxd/app_fastapi/
db_write_gateway.py # apply_write / replay_pending
sync_config.py
sync_binding.py
sync_context.py # Request → WriteContext
sync_replay_worker.py
database_fastapi.py # 写路由改走网关 + /sync/* API
```
### 同步 API
- `GET /database/sync/status`
- `POST /database/sync/binding/ensure`
- `GET /database/sync/binding`
- `GET /database/sync/pending`
- `POST /database/sync/replay` body: `{ "limit": 50 }`
请求头需带:`Database-ID``User-ID`(或应用已登录)、可选 `Tenant-ID` / `Authorization`
### 写路径行为(`online_primary`
```text
联网先写线上Database-ID=online_db_id→ 成功再写本地镜像 → synced=true
离线 pending_log不写正式本地业务结果 → 入 sync_pending 队列 → pending=true
离线 reject直接失败
回放:按 id 升序提交线上 → 成功后写本地并删队列记录;失败即停保序
```
绑定键:`(tenant_id, user_id, local_database_id) → online_db_id`(全局唯一)。
---
## 一、原状结论(改造前)
| 项 | 原状 |
|----|------|
| 写入口 | `/database/permanent/table/data/insert\|update\|update/id\|delete``/permanent/sql` 等 |
| 落库方式 | 直接 `PermanentDatabaseManager`**只写本地 SQLite** |
| 队列能力 | `queue_database_fastapi.py` 与 permanent **未打通** |
| 线上主写 / 断网日志 | **未实现** |
---
## 二、目标模型
```text
联网API 写 → 先写线上主库 → 再写本地镜像
断网API 写 → pending 日志queue_database→ 不 formal commit
恢复:有序回放到线上主 → 成功再对齐本地
```
硬约束:主写在线上;断网日志只能回放到线上主;断网窗口非强一致。
---
## 三~十、设计说明(保留)
原 P0P4、响应约定、勿做事项、分阶段 M1M4 已按上文落地M5SQL/导入全收口 + 冲突监控)待续。
与智建平台 dbsync客户端强一致仍以「API 同步写线上」为准,不要只靠触发器异步 outbox 充当主路径。
本意见文档:`E:\project\ai建站\database_fastapi修改意见.md`
实现目录:`yuhengyihao_client\yxd\app_fastapi\`