From bd3a4ac70bc25346d1b6656b68c6c06e434ffaf9 Mon Sep 17 00:00:00 2001 From: snowy-yang <102860110+snowy-yang@users.noreply.github.com> Date: Sat, 26 Sep 2026 14:15:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=20core/auth=5Fsystem?= =?UTF-8?q?=20=E7=9A=84=E6=95=B0=E6=8D=AE=E7=9B=AE=E5=BD=95=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E6=B6=88=E9=99=A4=E8=84=91=E8=A3=82=E9=9A=90?= =?UTF-8?q?=E6=82=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为什么:`core/db.py` 认 SITE_DATA_DIR、`auth_system/db.py` 写死 Path('data'), 而两处指向的是**同一个** data/site.db。web/main.py 的文档字符串还宣称 「数据目录可由 SITE_DATA_DIR 覆盖」——只有 core 侧做到了。 后果:只要运维真的设置 SITE_DATA_DIR,站点库(用户/账本/卡密)与 core 侧读的设置/公告就会落到两个不同文件,且**不会报错**—— 表现为「设置改了不生效」「公告消失」这类极难排查的诡异现象。 全仓 grep 确认该变量当前只出现在 core/db.py 与 web/main.py 两处, 没有任何测试或部署在用,所以是纯隐性隐患。 顺带修一个实测到的坑:`os.environ.get('SITE_DATA_DIR', 'data')` 的默认值 只在变量**缺失**时生效,`SITE_DATA_DIR=`(空串,compose/K8s 里很常见) 会让 Path('') 退化成当前工作目录,数据库静默落到 CWD。改用 `or 'data'`。 验证:四种取值(未设置 / 空串 / 绝对路径 / 相对路径)下 core.DATA_DIR == auth_system.DATA_DIR 且 DB_PATH 相同,全部一致。 --- auth_system/db.py | 5 ++++- core/db.py | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/auth_system/db.py b/auth_system/db.py index 7f035ad..bf91867 100644 --- a/auth_system/db.py +++ b/auth_system/db.py @@ -20,7 +20,10 @@ from .security import ( ) # ============ 路径与常量 ============ -DATA_DIR = Path('data') +# 必须与 core.db.DATA_DIR 用**同一条**表达式:两处指向同一个 data/site.db。 +# 此前这里写死 Path('data') 而 core 侧认 SITE_DATA_DIR——一旦运维设置该变量, +# 站点库与设置/公告库会落到两个不同文件(脑裂),且不会报错。 +DATA_DIR = Path(os.environ.get('SITE_DATA_DIR') or 'data') DB_PATH = DATA_DIR / 'site.db' diff --git a/core/db.py b/core/db.py index 3c14f6e..35dd59a 100644 --- a/core/db.py +++ b/core/db.py @@ -21,8 +21,12 @@ from typing import Any import aiosqlite -# 站点数据目录(可经环境变量覆盖,便于测试隔离) -DATA_DIR = Path(os.environ.get('SITE_DATA_DIR', 'data')) +# 站点数据目录(可经环境变量覆盖,便于测试隔离)。 +# 用 `or 'data'` 而不是 get 的默认值:get 的默认只在变量**缺失**时生效, +# 而 `SITE_DATA_DIR=`(空串)会让 Path('') 退化成当前工作目录, +# 数据库静默落到 CWD 而不是 data/。 +# 注意:auth_system.db.DATA_DIR 必须与此处保持同一条表达式(两者指向同一个库) +DATA_DIR = Path(os.environ.get('SITE_DATA_DIR') or 'data') DB_PATH = DATA_DIR / 'site.db' # 锁按事件循环隔离:asyncio.Lock 绑定创建它的 loop,跨 loop 复用会抛