"""matches.source_event_id 部分唯一索引 业务唯一键:同联赛同主客同自然天一条(ix_matches_unique,既有)。 source_event_id 是上游 bzzoiro 的比赛 id,用于统计回填与血缘追踪; 当它非空时应全局唯一(同一 upstream 比赛只对应一行 matches), 避免同一场比赛因自然键天级舍入差异产生重复。 partial unique(WHERE source_event_id IS NOT NULL): - 兼容存量空 source_event_id 的历史行(不强制回填); - 新采集行均带 source_event_id,从此具备 upstream 唯一性。 Revision ID: 0021_match_source_event_id_unique Revises: 0020_team_aliases Create Date: 2026-09-22 """ from typing import Sequence, Union from alembic import op revision: str = '0021_match_source_event_id_unique' down_revision: Union[str, None] = '0020_team_aliases' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.create_index( 'ix_matches_source_event_id_unique', 'matches', ['source_event_id'], unique=True, postgresql_where=op.text('source_event_id IS NOT NULL'), ) def downgrade() -> None: op.drop_index('ix_matches_source_event_id_unique', table_name='matches')