From 47ed6ec3f62c51af3f2bc1be6396776937ed4934 Mon Sep 17 00:00:00 2001 From: wangyunlong <3080433063@qq.com> Date: Tue, 27 Oct 2026 09:58:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(content-marketing):=20=E7=AC=94=E8=AE=B0?= =?UTF-8?q?=E5=BD=92=E5=B1=9E=E6=AC=BE=E6=94=B9=E6=8C=82=20dim=5Fstyle=20?= =?UTF-8?q?=E4=B8=BB=E6=A1=A3=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 并告警,待收录后归一。 --- .../modules/content_marketing/data/tools/db.py | 17 +++++++++++++++++ .../data/tools/feishu_comment_batch.py | 7 ++++++- .../data/tools/sync_metrics_to_cmt_notes.py | 16 ++++++++++++++-- .../data/tools/sync_notes_master.py | 16 ++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/gyxx_flow/modules/content_marketing/data/tools/db.py b/src/gyxx_flow/modules/content_marketing/data/tools/db.py index 64d2f7e..572fdee 100644 --- a/src/gyxx_flow/modules/content_marketing/data/tools/db.py +++ b/src/gyxx_flow/modules/content_marketing/data/tools/db.py @@ -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 # --------------------------------------------------------------------------- diff --git a/src/gyxx_flow/modules/content_marketing/data/tools/feishu_comment_batch.py b/src/gyxx_flow/modules/content_marketing/data/tools/feishu_comment_batch.py index 30c6364..d1def35 100644 --- a/src/gyxx_flow/modules/content_marketing/data/tools/feishu_comment_batch.py +++ b/src/gyxx_flow/modules/content_marketing/data/tools/feishu_comment_batch.py @@ -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, diff --git a/src/gyxx_flow/modules/content_marketing/data/tools/sync_metrics_to_cmt_notes.py b/src/gyxx_flow/modules/content_marketing/data/tools/sync_metrics_to_cmt_notes.py index 3016a2a..4c41ad1 100644 --- a/src/gyxx_flow/modules/content_marketing/data/tools/sync_metrics_to_cmt_notes.py +++ b/src/gyxx_flow/modules/content_marketing/data/tools/sync_metrics_to_cmt_notes.py @@ -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: diff --git a/src/gyxx_flow/modules/content_marketing/data/tools/sync_notes_master.py b/src/gyxx_flow/modules/content_marketing/data/tools/sync_notes_master.py index a039262..0da03a3 100644 --- a/src/gyxx_flow/modules/content_marketing/data/tools/sync_notes_master.py +++ b/src/gyxx_flow/modules/content_marketing/data/tools/sync_notes_master.py @@ -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