docs+feat: matches 唯一键语义明确化 + source_event_id partial unique

docs/05-data.md:业务唯一=同联赛同主客同自然天;
source_event_id 用于统计回填与血缘,新增部分唯一索引说明与 upsert 查找顺序。

新增 ix_matches_source_event_id_unique(WHERE IS NOT NULL),
兼容存量空值历史行;MatchRepository.find_by_source_event_id;
events upsert 优先按 event_id 定位,回退自然键。
迁移 0021 + 回归测试修复(find_by_source_event_id 方法调用误判)。
This commit is contained in:
shangfangjian
2026-09-22 00:41:54 +08:00
parent e15b554ba3
commit 7593b99e39
5 changed files with 82 additions and 7 deletions
+10 -3
View File
@@ -181,9 +181,16 @@ class BzzoiroSource:
away_team_id = away.id
team_name_to_id[nm.away_team] = away_team_id
# 查找已有比赛: 内存查找
match_key = _match_key(home_team_id, away_team_id, nm.date)
existing_match = existing_matches.get(match_key)
# 查找已有比赛:优先按 upstream event_id 定位(命中即唯一),
# 否则回退自然键(联赛+主客+天级日期)内存查找。
# source_event_id 上有 partial unique 索引保障 upstream 唯一。
eid = _to_int_or_none(raw.get("id"))
existing_match = None
if eid is not None:
existing_match = await match_r.find_by_source_event_id(eid)
if existing_match is None:
match_key = _match_key(home_team_id, away_team_id, nm.date)
existing_match = existing_matches.get(match_key)
if existing_match is None:
m = Match(