67 lines
2.6 KiB
Python
67 lines
2.6 KiB
Python
from __future__ import annotations
|
||
|
||
import enum
|
||
from datetime import datetime
|
||
from typing import Any
|
||
|
||
from sqlalchemy import JSON, Boolean, DateTime, Enum, ForeignKey, Integer, String, Text, func
|
||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
||
|
||
|
||
class Base(DeclarativeBase):
|
||
pass
|
||
|
||
|
||
class Job(Base):
|
||
__tablename__ = "jobs"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
cron_expr: Mapped[str] = mapped_column(String, nullable=False)
|
||
handler_path: Mapped[str] = mapped_column(String, nullable=False)
|
||
public_cfg: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False)
|
||
# 密文 token(Fernet 加密后的字符串)
|
||
secret_cfg: Mapped[str] = mapped_column(Text, default="", nullable=False)
|
||
|
||
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||
last_run_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
||
updated_at: Mapped[datetime] = mapped_column(
|
||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False
|
||
)
|
||
|
||
logs: Mapped[list["JobLog"]] = relationship(back_populates="job", cascade="all, delete-orphan")
|
||
|
||
|
||
class JobStatus(str, enum.Enum):
|
||
RUNNING = "RUNNING"
|
||
SUCCESS = "SUCCESS"
|
||
FAILURE = "FAILURE"
|
||
RETRY = "RETRY"
|
||
|
||
|
||
class JobLog(Base):
|
||
__tablename__ = "job_logs"
|
||
|
||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||
job_id: Mapped[str] = mapped_column(ForeignKey("jobs.id"), index=True, nullable=False)
|
||
|
||
status: Mapped[JobStatus] = mapped_column(
|
||
Enum(JobStatus, native_enum=False, length=16),
|
||
nullable=False,
|
||
)
|
||
snapshot_params: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False)
|
||
|
||
message: Mapped[str] = mapped_column(Text, default="", nullable=False)
|
||
traceback: Mapped[str] = mapped_column(Text, default="", nullable=False)
|
||
# 本次执行期间捕获到的完整运行日志(可能很长,按上层捕获器做截断)
|
||
run_log: Mapped[str] = mapped_column(Text, default="", nullable=False)
|
||
celery_task_id: Mapped[str] = mapped_column(String, default="", nullable=False)
|
||
attempt: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
||
|
||
started_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
||
finished_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||
|
||
job: Mapped[Job] = relationship(back_populates="logs")
|
||
|
||
|