fix(content-marketing): 笔记归属款改挂 dim_style 主档 id

data-hub 按 dim_style(系列锚点款)口径消费 cmt_notes_master.style_id,
直接写 cmt_styles.id 在款式主档重排后变成悬挂 id,笔记在系统中消失。
新增 db.get_dim_style_id,采集写入(feishu_comment_batch / sync_notes_master)
与指标回填(sync_metrics_to_cmt_notes)统一切换为 dim_style 优先、
按款名解析;新款未收录款式库时回退 cmt_styles.id 并告警,待收录后归一。
This commit is contained in:
wangyunlong committed 2026-10-27 09:58:27 +08:00
1 parent b1861f69cd
commit 47ed6ec3f6
4 files changed
+53 -3

No files matched your search

@@ -166,6 +166,23 @@ def get_style_id(name: str) -> int | None:
return row["id"] if row else None
def get_dim_style_id(name: str) -> int | None:
"""按款式名解析 dim_style 主档 id(2026-10-27 新增)。
data-hub 消费 cmt_notes_master.style_id 时按 dim_style(系列锚点款)口径,
cmt_styles.id 在款式主档重排后会变成悬挂 id;写笔记前用本函数归一,
解析不到返回 None(新款尚未收录款式库,由调用方决定回退策略)。
"""
with get_dict_conn() as conn:
with conn.cursor(row_factory=dict_row) as cur:
cur.execute(
"SELECT id FROM dim_style WHERE style_name = %s ORDER BY id LIMIT 1",
(name,),
)
row = cur.fetchone()
return row["id"] if row else None
# ---------------------------------------------------------------------------
# Creators
# ---------------------------------------------------------------------------
@@ -362,9 +362,14 @@ def sync_notes_to_db(note_tasks: list[NoteTask], style_ids: dict[str, int]) -> d
creator_id = creator_ids[creator_name]
db.link_style_creator(style_id, creator_id)
# 2026-10-27 起笔记归属改挂 dim_style 主档 id(data-hub 消费口径),
# cmt_styles.id 仅供 cmt_style_creators 等采集端内部关系表使用;
# dim_style 缺同名款时回退 cmt_styles.id,待款式收录后归一
dim_style_id = db.get_dim_style_id(task.style_name) or style_id
platform = detect_platform(task.note_url, task.platform_hint)
note_id = db.upsert_note(
style_id=style_id,
style_id=dim_style_id,
creator_id=creator_id,
platform=platform,
url=task.note_url,
@@ -426,9 +426,21 @@ def _backfill_record(mapping: dict, style_name: str, rid: str) -> dict | None:
def _style_id_lookup(cur) -> dict[str, int]:
"""name -> cmt_styles.id 映射(一次查全表)"""
"""name -> 笔记归属款 id 映射(一次查全表)。
2026-10-27 起优先 dim_style 主档 id(data-hub 按 dim_style 消费;直接用
cmt_styles.id 在款式主档重排后会变成悬挂 id,笔记在系统中"消失")。
dim_style 缺同名款时回退 cmt_styles.id,待款式收录 + 存量重映射迁移归一。
同名多行取最小 id。
"""
mapping: dict[str, int] = {}
cur.execute("SELECT style_name, id FROM dim_style ORDER BY id")
for name, sid in cur.fetchall():
mapping.setdefault(str(name), sid)
cur.execute("SELECT id, name FROM cmt_styles")
return {name: id for id, name in cur.fetchall()}
for sid, name in cur.fetchall():
mapping.setdefault(str(name), sid)
return mapping
def _ensure_creator(cur, name: str | None) -> int | None:
@@ -479,6 +479,22 @@ def sync_table(
raise ValueError("mapping 缺少款式/base_token/table_id")
style_id = _ensure_style(cur, style_name)
# 2026-10-27 起笔记归属改挂 dim_style 主档 id(data-hub 按 dim_style 系列锚点款消费,
# 历史上直接写 cmt_styles.id 在款式主档重排后变成悬挂 id,导致笔记在系统里"消失")。
# 按款名解析 dim_style.id;解析不到(新款尚未收录款式库)时回退 cmt_styles.id 并告警,
# 后续由款式收录 + 存量重映射迁移归一。
cur.execute(
"SELECT id FROM dim_style WHERE style_name = %s ORDER BY id LIMIT 1",
(style_name,),
)
dim_row = cur.fetchone()
if dim_row:
style_id = dim_row[0]
else:
_log(
f"[{style_name}] dim_style 未找到同名款式,笔记暂挂 cmt_styles.id={style_id},"
"待款式收录后归一"
)
creators = 0
for row in rows:
creator_id: int | None = None