mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 22:11:58 +00:00
3e922cbefb
- 先停服务:来源旁边留着 agentlab.db-wal / checkpoints.db-wal(还有连接开着,或者上次是强杀),或者目标库上有 application_name=agentlab 的连接,就拒绝,什么都不写;强杀留下的 -wal 用 --assume-stopped 放过。查不到的(另一台机器上的服务)在说明里写明要自己保证 - 读快照:SQLite 备份接口拷到 --work-dir(缺省系统临时目录),在拷贝上跑一遍启动时的建表补列,老版本的库按当前表结构读;来源按读写打开、只许读(mode=ro 打开 WAL 库会留下它自己建的 -wal,下一次导入就当成服务还开着) - 目标:同启动时的 create_schema 建表;按外键先后逐表、按主键分批 INSERT … ON CONFLICT DO NOTHING——目标上已有同一主键(或撞了别的唯一约束)的行一律不动,重跑只补没有的;整批撞了外键之类的约束就逐行重试,插不进的列出主键和原因;自增主键的序列接到导入的最大值后面 - 值:按模型的列类型读写(时间、布尔),JSON 原文照搬(SQL 的 NULL 和 JSON 的 null 分开、键的先后不变);PostgreSQL 不收的(NaN、NUL、整数列里的浮点和数字字符串、文本列里的非文本)换掉并计数打印 - 断点:用两个 saver 的公开接口逐条读出写入(含 pending writes,特殊通道和普通写入分开写,序号同来源),目标上已有的断点不重写;按线程核对断点和 pending writes 的条数 - 核对:每张表按主键数来源的行目标上有没有(导入前已有、这次补上分开数),逐表打印;有没导进去的退出码非零。--dry-run 只核对、不建表不写 - 测试:另起进程在 SQLite 数据目录里跑一次停在审批上的运行(事件、审批、待办、工件引用),导入新建的空库、再导一遍什么都不重复,再另起进程连这个 PostgreSQL、同一个数据目录批掉审批,运行从断点接着跑完、事件序号接着往下编、工件读得到、新的变化记录的序号接在导入的后面;dry-run 不写;目标上服务还连着就拒绝;来源、参数、值转换的单测
32 lines
1.1 KiB
Python
32 lines
1.1 KiB
Python
"""应用库的维护命令:python -m app.db <命令>。
|
||
|
||
copy-to-postgres 把 SQLite 数据目录里的应用库和断点导入 PostgreSQL(db/to_postgres.py;先停服务)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
|
||
COMMANDS = {"copy-to-postgres": "把 SQLite 数据目录里的应用库和断点导入 PostgreSQL(先停服务)"}
|
||
|
||
|
||
def main(argv: list[str] | None = None) -> int:
|
||
args = list(sys.argv[1:] if argv is None else argv)
|
||
if not args or args[0] in ("-h", "--help"):
|
||
print("用法:python -m app.db <命令> [参数]\n")
|
||
for name, what in COMMANDS.items():
|
||
print(f" {name:<18}{what}")
|
||
print("\n各命令加 --help 看参数")
|
||
return 0 if args else 2
|
||
command, rest = args[0], args[1:]
|
||
if command == "copy-to-postgres":
|
||
from app.db.to_postgres import main as copy_main
|
||
|
||
return copy_main(rest)
|
||
print(f"认不出的命令:{command}(可用的:{'、'.join(COMMANDS)})", file=sys.stderr)
|
||
return 2
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|