""" 节目期次模型 — SQLModel 业务规则(.clinerules 5.3 软引用 + 快照模式): - editor_id 可空(离职编导) - editor_name_snapshot 必填(历史导入也走快照) - 查询历史作品:先 editor_id,回退 editor_name_snapshot 文本匹配 """ from datetime import date, datetime from sqlalchemy import Column from sqlalchemy import DateTime as SADateTime from sqlalchemy import Text from sqlalchemy import Boolean as SABoolean from sqlalchemy import Integer as SAInteger from sqlalchemy import Numeric as SANumeric from sqlalchemy.sql import func as sa_func from sqlmodel import Field, SQLModel class Episode(SQLModel, table=True): __tablename__ = "episodes" id: int | None = Field(default=None, primary_key=True) episode_number: int = Field(unique=True, index=True) program_name: str = Field(max_length=200) air_date: date # 编导(软引用 + 快照双字段) # 在职编导:editor_id 和 editor_name_snapshot 都填 # 离职编导:editor_id 留空,editor_name_snapshot 填姓名 editor_id: int | None = Field(default=None, foreign_key="users.id") editor_name_snapshot: str = Field(max_length=100) # 收视数据 # 注意:.clinerules 5.1 颜色只对 audience_share 上色 # audience_rating 只展示数字,不参与颜色判定 audience_share: float | None = Field(default=None) audience_rating: float | None = Field(default=None) # 重播相关 is_rerun: bool = Field(default=False) original_episode_id: int | None = Field(default=None, foreign_key="episodes.id") is_time_sensitive: bool = Field(default=False) # 外拍信息 is_outdoor_shoot: bool = Field(default=False) outdoor_contact_person: str | None = Field(default=None, max_length=100) outdoor_contact_info: str | None = Field(default=None, max_length=200) # 线索 lead_source: str | None = Field(default=None, max_length=300) # 责编备注 notes: str | None = Field(default=None) created_at: datetime | None = Field( default=None, sa_column=Column(SADateTime(timezone=True), nullable=False, server_default=sa_func.now()), ) updated_at: datetime | None = Field( default=None, sa_column=Column(SADateTime(timezone=True), nullable=False, server_default=sa_func.now()), )