""" 任务实例模型 用于存储任务管理表的数据,记录每次编辑任务的实例 """ from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, ForeignKey, JSON, Enum, Index from sqlalchemy.orm import relationship, foreign from sqlalchemy.sql.expression import and_ from datetime import datetime import enum import uuid from data.models.base import BaseModel class TaskInstanceStatus(enum.Enum): """任务实例状态枚举""" EDITING = "editing" # 编辑中 PUBLISHED = "published" # 已发布 class TaskInstance(BaseModel): """任务实例模型""" __tablename__ = "task_instances" instance_id = Column(String(36), nullable=False, unique=True, index=True, comment="实例唯一ID,用于外部引用") task_id = Column(String(50), ForeignKey("tasks.task_id"), nullable=False, comment="关联的任务ID") name = Column(String(100), nullable=False, comment="任务名称(复制自任务表)") variables = Column(JSON, nullable=True, comment="任务变量") priority = Column(Integer, default=1, comment="任务优先级") block_outputs = Column(JSON, nullable=True, comment="块输出参数") context_params = Column(JSON, nullable=True, comment="上下文参数") status = Column(Enum(TaskInstanceStatus), default=TaskInstanceStatus.EDITING, comment="任务实例状态") # 确保创建索引 __table_args__ = ( Index('idx_task_instances_instance_id', 'instance_id'), {'mysql_engine': 'InnoDB'} ) # 关联关系 - 使用foreign()显式标记外键 task = relationship("Task", back_populates="instances") input_params = relationship( "TaskInputParam", back_populates="instance", primaryjoin="and_(foreign(TaskInstance.instance_id)==TaskInputParam.instance_id, " "TaskInputParam.is_deleted==False)", viewonly=False, cascade="all" # 移除delete-orphan级联选项 ) def __init__(self, **kwargs): """初始化实例,自动生成instance_id""" if 'instance_id' not in kwargs: kwargs['instance_id'] = str(uuid.uuid4()) super(TaskInstance, self).__init__(**kwargs) def to_dict(self): """转换为字典""" return { "id": self.instance_id, # 使用instance_id作为对外ID "instance_id": self.instance_id, "task_id": self.task_id, "name": self.name, "variables": self.variables or {}, "priority": self.priority, "block_outputs": self.block_outputs or {}, "context_params": self.context_params or {}, "status": self.status.value if self.status else None, "created_at": int(self.created_at.timestamp() * 1000) if self.created_at else None, "updated_at": int(self.updated_at.timestamp() * 1000) if self.updated_at else None, "is_deleted": self.is_deleted } def to_api_dict(self): """转换为API响应字典,只返回必要的字段""" return { "instance_id": self.instance_id, "task_id": self.task_id, "name": self.name, "variables": self.variables or {}, "priority": self.priority, "block_outputs": self.block_outputs or {}, "context_params": self.context_params or {}, "status": self.status.value if self.status else None }