""" DecodeVideo 模型 对应数据库表 decode_videos 的 ORM 模型 """ from enum import IntEnum from typing import Optional from sqlalchemy import Column, String, BigInteger, Integer, Text, DateTime from sqlalchemy.sql import func from src.models.database import Base from src.utils.logger import get_logger logger = get_logger(__name__) class DecodeStatus(IntEnum): """解码状态枚举 对应数据库字段 status 的值: - PENDING: 0 - 待执行 - EXECUTING: 1 - 执行中 - SUCCESS: 2 - 执行成功 - FAILED: 3 - 执行失败 """ PENDING = 0 EXECUTING = 1 SUCCESS = 2 FAILED = 3 @classmethod def get_description(cls, status: int) -> str: """获取状态描述 Args: status: 状态值 Returns: str: 状态描述 """ descriptions = { cls.PENDING: "待执行", cls.EXECUTING: "执行中", cls.SUCCESS: "执行成功", cls.FAILED: "执行失败", } return descriptions.get(status, "未知状态") class DecodeVideo(Base): """解码视频模型 对应数据库表: decode_videos 字段说明: - video_id: 视频ID (varchar(100), nullable) - task_id: 任务ID (bigint, not null) - result: 解码结果 (mediumtext, nullable) - decode_result_v2: 解码结果V2 (mediumtext, nullable) - ScriptWorkflowV2分支的结果 - search_keywords: 搜索关键词 (text, nullable) - 字符串数组的JSON格式 - status: 状态 (int, nullable) - 0:待执行 / 1:执行中 / 2:执行成功 / 3:执行失败 - error_reason: 失败原因 (mediumtext, nullable) """ __tablename__ = "decode_videos" # 主键:使用 task_id 作为主键(根据业务需求,可能需要调整) task_id = Column(BigInteger, primary_key=True, nullable=False, comment="任务ID") # 视频ID video_id = Column(String(100), nullable=True, index=True, comment="视频ID") # 解码结果(JSON 格式) result = Column(Text, nullable=True, comment="解码结果") # 解码结果V2(分支2的结果,JSON 格式) decode_result_v2 = Column(Text, nullable=True, comment="解码结果V2(ScriptWorkflowV2分支结果)") # 搜索关键词(字符串数组的JSON格式) search_keywords = Column(Text, nullable=True, comment="搜索关键词(字符串数组的JSON格式)") # 状态 status = Column(Integer, nullable=True, default=int(DecodeStatus.PENDING), index=True, comment="状态: 0:待执行 / 1:执行中 / 2:执行成功 / 3:执行失败") # 失败原因 error_reason = Column(Text, nullable=True, comment="失败原因") # 时间戳字段(可选,用于记录创建和更新时间) created_at = Column(DateTime, nullable=True, server_default=func.now(), comment="创建时间") updated_at = Column(DateTime, nullable=True, server_default=func.now(), onupdate=func.now(), comment="更新时间") def __repr__(self) -> str: """对象字符串表示""" return f"" def to_dict(self) -> dict: """转换为字典 Returns: dict: 模型数据字典 """ return { "task_id": self.task_id, "video_id": self.video_id, "result": self.result, "decode_result_v2": self.decode_result_v2, "search_keywords": self.search_keywords, "status": self.status, "error_reason": self.error_reason, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None, } @classmethod def create( cls, task_id: int, video_id: Optional[str] = None, status: Optional[int] = None, result: Optional[str] = None, decode_result_v2: Optional[str] = None, error_reason: Optional[str] = None ) -> "DecodeVideo": """创建新的解码视频记录 Args: task_id: 任务ID video_id: 视频ID status: 状态(默认: PENDING) result: 解码结果 decode_result_v2: 解码结果V2(ScriptWorkflowV2分支结果) error_reason: 失败原因 Returns: DecodeVideo: 新创建的模型实例 """ # 统一将枚举转换为整型值 if status is None: status_value = int(DecodeStatus.PENDING) else: try: # 支持传入 IntEnum 或具体的整数 status_value = int(status) except Exception: status_value = int(DecodeStatus.PENDING) return cls( task_id=task_id, video_id=video_id, status=status_value, created_at=func.now(), result=result, decode_result_v2=decode_result_v2, error_reason=error_reason ) def update_status(self, status: DecodeStatus, error_reason: Optional[str] = None): """更新状态 Args: status: 新状态 error_reason: 失败原因(仅在失败时使用) """ self.status = status.value if status == DecodeStatus.FAILED and error_reason: self.error_reason = error_reason elif status != DecodeStatus.FAILED: self.error_reason = None def update_result(self, result: str): """更新解码结果 Args: result: 解码结果(JSON 字符串) """ self.result = result if self.status == DecodeStatus.EXECUTING: self.update_status(DecodeStatus.SUCCESS) def update_result_v2(self, result_v2: str): """更新解码结果V2(ScriptWorkflowV2分支结果) Args: result_v2: 解码结果V2(JSON 字符串) """ self.decode_result_v2 = result_v2 def update_search_keywords(self, search_keywords: str): """更新搜索关键词(字符串数组的JSON格式) Args: search_keywords: 搜索关键词(字符串数组的JSON格式,如:["关键词1", "关键词2"]) """ self.search_keywords = search_keywords