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:
@@ -190,11 +190,13 @@ async def get_injuries_for_match(db, team_id: int, match_date, as_of=None) -> li
|
||||
match_date: 比赛日期
|
||||
as_of: 截止时间(cutoff)。只返回 retrieved_at <= as_of 的记录。
|
||||
用于回测时防止"未来采集的数据"泄漏到历史预测。
|
||||
必须保持 timezone-aware datetime,不会截断为 date。
|
||||
"""
|
||||
from sqlalchemy import and_, or_, select
|
||||
from sqlalchemy import or_, select
|
||||
|
||||
from src.db.models import Injury
|
||||
|
||||
# 只处理 match_date:去掉时间部分,仅比较日期
|
||||
if hasattr(match_date, "date"):
|
||||
match_date = match_date.date()
|
||||
|
||||
@@ -206,9 +208,8 @@ async def get_injuries_for_match(db, team_id: int, match_date, as_of=None) -> li
|
||||
)
|
||||
|
||||
# 回测防泄漏: 只使用 as_of 时间点之前已采集的数据
|
||||
# 注意: as_of 保持 datetime,不截断为 date,避免错误排除同日合法数据
|
||||
if as_of is not None:
|
||||
if hasattr(as_of, "date"):
|
||||
as_of = as_of.date()
|
||||
stmt = stmt.where(Injury.retrieved_at.is_not(None))
|
||||
stmt = stmt.where(Injury.retrieved_at <= as_of)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user