feat: P0-02/P0-03/P0-05 数据库时间语义与约束
P0-02: MatchStats 增加 source/source_record_id/retrieved_at/available_at
context_builder 过滤统计数据时检查 available_at <= cutoff
P0-03: Prediction 增加 match_kickoff_at/prediction_created_at/prediction_cutoff_at
明确区分比赛时间/预测创建时间/数据截止时间
P0-05: Prediction 增加 status 字段(success/failed/degraded)
数据库 CHECK 约束
Alembic: 0005_prediction_status_and_stats_provenance
P1-02: injuries as_of 不再截断为 date,保持 datetime 精度
This commit is contained in:
+12
-2
@@ -115,6 +115,11 @@ class MatchStats(Base):
|
||||
home_red_cards: Mapped[int | None] = mapped_column(Integer)
|
||||
away_red_cards: Mapped[int | None] = mapped_column(Integer)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow)
|
||||
# 数据血缘:追踪统计数据的来源和可用时间
|
||||
source: Mapped[str | None] = mapped_column(String(30)) # bzzoiro / understat
|
||||
source_record_id: Mapped[str | None] = mapped_column(String(100))
|
||||
retrieved_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
available_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
|
||||
match: Mapped[Match] = relationship(back_populates="stats")
|
||||
|
||||
@@ -163,8 +168,12 @@ class Prediction(Base):
|
||||
# multi-agent 模式: 各专家报告
|
||||
mode: Mapped[str] = mapped_column(String(20), nullable=False, default="single")
|
||||
agent_outputs: Mapped[dict | None] = mapped_column(JSONB)
|
||||
# 回测/可复现性
|
||||
cutoff_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
# 预测状态: success / failed / degraded
|
||||
status: Mapped[str] = mapped_column(String(20), nullable=False, default="success")
|
||||
# 时间语义:区分比赛时间、预测创建时间、数据截止时间
|
||||
match_kickoff_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
prediction_created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow)
|
||||
prediction_cutoff_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
input_hash: Mapped[str | None] = mapped_column(String(64))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow)
|
||||
actual_home_goals: Mapped[int | None] = mapped_column(Integer)
|
||||
@@ -182,4 +191,5 @@ class Prediction(Base):
|
||||
CheckConstraint("subjective_confidence >= 0 AND subjective_confidence <= 1", name="ck_confidence_range"),
|
||||
CheckConstraint("pred_1x2 IN ('1', 'X', '2')", name="ck_pred_1x2_enum"),
|
||||
CheckConstraint("mode IN ('single', 'multi')", name="ck_mode_enum"),
|
||||
CheckConstraint("status IN ('success', 'failed', 'degraded')", name="ck_status_enum"),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user