fix: resolve_project_id键漂移防护——传入值先按id校验,查不到按name反查归一为真实id,名字歧义拒绝;根治bid_chapters以项目名落库(陕西项目26条名字键孤儿行,与id键骨架并存形成双骨架)(2026-09-02)
This commit is contained in:
parent
1eafd7b1c3
commit
7a6a0350dc
@ -158,13 +158,36 @@ async def get_param(sor, key, default=""):
|
|||||||
|
|
||||||
|
|
||||||
async def resolve_project_id(project_id="", **entity_ids):
|
async def resolve_project_id(project_id="", **entity_ids):
|
||||||
"""补齐 project_id:调用方(会话上下文)已给则原样返回;否则从实体反查项目。
|
"""补齐/校验 project_id:必须是 sd_projects 真实存在的项目。
|
||||||
|
|
||||||
角色工具经引擎分发时默认注入会话当前项目;为空时(无会话上下文)按实体反查,
|
角色工具经引擎分发时默认注入会话当前项目;为空时(无会话上下文)按实体反查,
|
||||||
避免「项目不明」导致跨项目读写。全部反查失败抛 ValueError。
|
避免「项目不明」导致跨项目读写。全部反查失败抛 ValueError。
|
||||||
|
|
||||||
|
键漂移防护(2026-09-02):调用方可能把项目「名字」误当 project_id 传入
|
||||||
|
(曾致 bid_chapters 26 条记录以名字为键落库,与正确 id 键骨架并存形成双骨架)。
|
||||||
|
此处统一校验:传入值先按 id 查;查不到再按 name 反查并归一为真实 id;
|
||||||
|
名字命中多个项目则拒绝(歧义),彻底堵住「名字当 id」写库。
|
||||||
"""
|
"""
|
||||||
if project_id:
|
if project_id:
|
||||||
return project_id
|
db, dbname = get_db()
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
recs = await sor.sqlExe(
|
||||||
|
"SELECT id FROM sd_projects WHERE id=${p}$ LIMIT 1", {"p": project_id})
|
||||||
|
await sor.sqlExe("COMMIT", {})
|
||||||
|
if recs:
|
||||||
|
return project_id
|
||||||
|
# 按名字反查(键漂移容错:误传项目名 → 归一为真实 id)
|
||||||
|
recs = await sor.sqlExe(
|
||||||
|
"SELECT id FROM sd_projects WHERE name=${p}$", {"p": project_id})
|
||||||
|
await sor.sqlExe("COMMIT", {})
|
||||||
|
if len(recs) == 1:
|
||||||
|
real_id = getattr(recs[0], "id", "")
|
||||||
|
logger.warning("resolve_project_id: 项目名「%s」→ 归一为 id %s(键漂移防护)",
|
||||||
|
project_id, real_id)
|
||||||
|
return real_id
|
||||||
|
if len(recs) > 1:
|
||||||
|
raise ValueError("项目名「%s」匹配到多个项目,请改用项目 ID 指定" % project_id)
|
||||||
|
raise ValueError("项目不存在:%s" % project_id)
|
||||||
db, dbname = get_db()
|
db, dbname = get_db()
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
for tbl, col, val in (("bid_chapters", "chapter_id", entity_ids.get("chapter_id")),
|
for tbl, col, val in (("bid_chapters", "chapter_id", entity_ids.get("chapter_id")),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user