diff --git a/alembic/versions/coupon_claim_event.py b/alembic/versions/coupon_claim_event.py index 8161330..c3634d0 100644 --- a/alembic/versions/coupon_claim_event.py +++ b/alembic/versions/coupon_claim_event.py @@ -69,7 +69,11 @@ def upgrade() -> None: unique=False, ) - # 旧表只能回填当前仍保留的 trace;历史上已被每日去重覆盖的关联无法恢复。 + # 旧表按 (device, coupon, 自然日) 去重,trace_id 可空且不在唯一键里:同一 + # (trace_id, coupon_id) 可能散落在多行(如一次会话的 /step 帧跨零点,把同一张券 + # 写进相邻两天)。新表按 (trace_id, coupon_id) 唯一,整表 1:1 复制会撞 + # uq_coupon_claim_event_trace_coupon。回填时按 (trace_id, coupon_id) 只取 id 最大 + # (最近写入)的一行。历史上已被每日去重覆盖的关联仍无法恢复。 op.execute( """ INSERT INTO coupon_claim_event ( @@ -81,6 +85,12 @@ def upgrade() -> None: vendor, coupon_name, claimed_count, reason, extra, created_at, updated_at FROM coupon_claim_record WHERE trace_id IS NOT NULL + AND id IN ( + SELECT MAX(id) + FROM coupon_claim_record + WHERE trace_id IS NOT NULL + GROUP BY trace_id, coupon_id + ) """ )