feat(store_mapping): 加京东原料列 + upsert 首写泛化(任意平台首写不丢列)
京东秒送接入: 店铺身份是两个稳定数字 id —— storeId 进 id_jd(同 taobao shopId→id_taobao), venderId(deeplink 还需、商家维度)单列存 jd_vender_id; 另加 jd_share_url/jd_resolved_url/ jd_deeplink 原料列(与 taobao_*/meituan_* 平行)。迁移 store_mapping_jd_cols 加这 4 列 + jd_vender_id 索引。 顺手修一个潜在 bug: upsert 的首写(INSERT)原来硬编码只灌 taobao+通用列, 首写的若是美团/ 京东腿, 它们的列不在构造器里会被丢。改成按 _MERGE_COLUMNS 逐列 setattr, 任意平台首写都全量 落库(美团也受益)。合并(填空不覆盖)逻辑不变。 验证: 迁移单 head、store_mapping 无新漂移; TestClient 打真 PG —— 京东首写 4 列全落 → 淘宝同 trace 合并填淘宝列、不覆盖京东列。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
"""store_mapping 加京东原料列(jd_vender_id + 分享链/反查 URL/deeplink)
|
||||
|
||||
Revision ID: store_mapping_jd_cols
|
||||
Revises: store_mapping_meituan_cols
|
||||
Create Date: 2026-06-13 00:00:00.000000
|
||||
|
||||
京东秒送接入店内搜索 deeplink 链路: 3.cn 短链 → 跟随重定向反查 venderId+storeId →
|
||||
openapp.jdmobile:// deeplink。京东店铺身份是**两个**稳定数字 id: storeId 进 id_jd(稳定
|
||||
店主键, 同 taobao 的 shopId→id_taobao), venderId 进单列 jd_vender_id(deeplink 还需它)。
|
||||
其余三列与 taobao_*/meituan_* 原料列平行。
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'store_mapping_jd_cols'
|
||||
down_revision: Union[str, Sequence[str], None] = 'store_mapping_meituan_cols'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
with op.batch_alter_table('store_mapping', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('jd_vender_id', sa.String(length=64), nullable=True))
|
||||
batch_op.add_column(sa.Column('jd_share_url', sa.String(length=256), nullable=True))
|
||||
batch_op.add_column(sa.Column('jd_resolved_url', sa.Text(), nullable=True))
|
||||
batch_op.add_column(sa.Column('jd_deeplink', sa.Text(), nullable=True))
|
||||
batch_op.create_index(batch_op.f('ix_store_mapping_jd_vender_id'), ['jd_vender_id'], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
with op.batch_alter_table('store_mapping', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_store_mapping_jd_vender_id'))
|
||||
batch_op.drop_column('jd_deeplink')
|
||||
batch_op.drop_column('jd_resolved_url')
|
||||
batch_op.drop_column('jd_share_url')
|
||||
batch_op.drop_column('jd_vender_id')
|
||||
@@ -14,8 +14,8 @@ attrs(JSONB)兜底存灵活明细,免得每多记一个字段就迁移 schema。
|
||||
|
||||
⚠️ 数据质量:跨平台"同一家店"的连接来自 agent 的 LLM 店铺匹配,匹配错则一行里连错店。
|
||||
本表是 append-only 原始记录(每比价一行、trace_id 幂等防重试重复),清洗/归一二期再做。
|
||||
已接通**淘宝**(id_taobao=shopId)与**美团**(meituan_poi_id_str,非稳定主键、单列存);
|
||||
京东暂为 name-only 或空。
|
||||
已接通**淘宝**(id_taobao=shopId)、**美团**(meituan_poi_id_str,非稳定主键、单列存)、
|
||||
**京东**(id_jd=storeId + jd_vender_id,均稳定数字主键;3.cn 短链反查)。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ _MERGE_COLUMNS = (
|
||||
"source_device_id", "source_user_id",
|
||||
"taobao_share_url", "taobao_resolved_url", "taobao_deeplink",
|
||||
"meituan_poi_id_str", "meituan_share_url", "meituan_resolved_url", "meituan_deeplink",
|
||||
"jd_vender_id", "jd_share_url", "jd_resolved_url", "jd_deeplink",
|
||||
"attrs",
|
||||
)
|
||||
|
||||
@@ -58,28 +59,14 @@ def upsert(db: Session, payload: StoreMappingIn) -> tuple[int, int | None]:
|
||||
created=1 新建该 trace 的行 / 0 合并进已存在行(填空,不覆盖)。"""
|
||||
existing = _find(db, payload.trace_id)
|
||||
if existing is None:
|
||||
# 首写: 把 payload 全部可合并列灌进去(逐列 setattr 而非硬编码构造器, 否则首写的是
|
||||
# 美团/京东腿时它们的列会漏 —— 不在硬编码列表里就丢)。trace_id/business_type 是键/默认, 显式给。
|
||||
row = StoreMapping(
|
||||
trace_id=payload.trace_id,
|
||||
business_type=payload.business_type,
|
||||
source_platform=payload.source_platform,
|
||||
id_taobao=payload.id_taobao,
|
||||
name_taobao=payload.name_taobao,
|
||||
id_meituan=payload.id_meituan,
|
||||
name_meituan=payload.name_meituan,
|
||||
id_jd=payload.id_jd,
|
||||
name_jd=payload.name_jd,
|
||||
city=payload.city,
|
||||
geohash=payload.geohash,
|
||||
lng=payload.lng,
|
||||
lat=payload.lat,
|
||||
taobao_address=payload.taobao_address,
|
||||
source_device_id=payload.source_device_id,
|
||||
source_user_id=payload.source_user_id,
|
||||
taobao_share_url=payload.taobao_share_url,
|
||||
taobao_resolved_url=payload.taobao_resolved_url,
|
||||
taobao_deeplink=payload.taobao_deeplink,
|
||||
attrs=payload.attrs,
|
||||
)
|
||||
for col in _MERGE_COLUMNS:
|
||||
setattr(row, col, getattr(payload, col))
|
||||
db.add(row)
|
||||
try:
|
||||
db.commit()
|
||||
|
||||
@@ -45,6 +45,12 @@ class StoreMappingIn(BaseModel):
|
||||
meituan_resolved_url: str | None = None
|
||||
meituan_deeplink: str | None = None
|
||||
|
||||
# 京东原料(venderId 单列存, storeId 进 id_jd; 见 model 注释)
|
||||
jd_vender_id: str | None = None
|
||||
jd_share_url: str | None = None
|
||||
jd_resolved_url: str | None = None
|
||||
jd_deeplink: str | None = None
|
||||
|
||||
attrs: dict | None = None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user