97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
"""任务模型"""
|
|
from sqlalchemy import Column, String, Integer, DateTime, JSON, Enum, Text
|
|
from sqlalchemy.sql import func
|
|
import enum
|
|
|
|
from ..database import Base
|
|
|
|
|
|
class JobStatus(str, enum.Enum):
|
|
"""任务状态"""
|
|
PENDING = "pending" # 等待进入队列
|
|
QUEUED = "queued" # 已排队,等待执行
|
|
RUNNING = "running" # 正在执行
|
|
COMPLETED = "completed" # 执行完成
|
|
FAILED = "failed" # 执行失败
|
|
|
|
|
|
class StepStatus(str, enum.Enum):
|
|
"""步骤状态"""
|
|
PENDING = "PENDING"
|
|
RUNNING = "RUNNING"
|
|
SUCCESS = "SUCCESS"
|
|
FAILED = "FAILED"
|
|
SKIPPED = "SKIPPED"
|
|
|
|
|
|
class Job(Base):
|
|
__tablename__ = "jobs"
|
|
|
|
id = Column(String, primary_key=True, index=True)
|
|
celery_task_id = Column(String, nullable=True, index=True)
|
|
status = Column(Enum(JobStatus), default=JobStatus.PENDING, index=True)
|
|
|
|
input_files = Column(JSON)
|
|
sequence_type = Column(String, default="nucl")
|
|
scaf_suffix = Column(String, default=".fna")
|
|
threads = Column(Integer, default=4)
|
|
|
|
# 分析参数
|
|
min_identity = Column(Integer, default=80) # 存储为百分比 (0-100)
|
|
min_coverage = Column(Integer, default=60)
|
|
allow_unknown_families = Column(Integer, default=0) # 0 = False, 1 = True
|
|
require_index_hit = Column(Integer, default=1)
|
|
|
|
# CRISPR-Cas 参数
|
|
crispr_fusion = Column(Integer, default=0) # 0 = False, 1 = True
|
|
crispr_weight = Column(Integer, default=0) # 存储为百分比 (0-100)
|
|
|
|
result_url = Column(String, nullable=True)
|
|
logs = Column(Text, nullable=True)
|
|
error_message = Column(Text, nullable=True)
|
|
|
|
# 队列位置
|
|
queue_position = Column(Integer, nullable=True)
|
|
|
|
# 进度信息
|
|
current_stage = Column(String, nullable=True) # digger, shoter, plots, bundle
|
|
progress_percent = Column(Integer, default=0)
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now(), index=True)
|
|
started_at = Column(DateTime(timezone=True), nullable=True)
|
|
completed_at = Column(DateTime(timezone=True), nullable=True)
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
|
|
class Step(Base):
|
|
"""任务步骤"""
|
|
__tablename__ = "job_steps"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
job_id = Column(String, index=True) # ForeignKey("jobs.id") - simplified for SQLite/No-Relation
|
|
step_id = Column(String) # digger, shoter, etc.
|
|
name = Column(String)
|
|
status = Column(Enum(StepStatus), default=StepStatus.PENDING)
|
|
|
|
start_at = Column(DateTime(timezone=True), nullable=True)
|
|
end_at = Column(DateTime(timezone=True), nullable=True)
|
|
duration_ms = Column(Integer, nullable=True)
|
|
|
|
summary = Column(Text, nullable=True)
|
|
error = Column(Text, nullable=True)
|
|
|
|
|
|
class JobLog(Base):
|
|
"""任务日志"""
|
|
__tablename__ = "job_logs"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
job_id = Column(String, index=True)
|
|
step_id = Column(String, nullable=True)
|
|
|
|
level = Column(String, default="INFO")
|
|
message = Column(Text)
|
|
timestamp = Column(DateTime(timezone=True), server_default=func.now())
|
|
seq = Column(Integer, default=0)
|
|
|