Files
bttoxin-pipeline/backend/app/models/job.py

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)