from datetime import datetime from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base class Job(Base): """备份任务定义。 source_config_json 是 Fernet 加密的 JSON: - mysql: {"host", "port", "user", "password", "database"} - directory: {"path", "exclude_patterns": [...]} """ __tablename__ = "jobs" id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) type: Mapped[str] = mapped_column(String(16), nullable=False) # 'mysql' / 'directory' source_config_json: Mapped[str] = mapped_column(Text, nullable=False) storage_id: Mapped[int] = mapped_column( Integer, ForeignKey("storages.id", ondelete="RESTRICT"), nullable=False ) cron_expression: Mapped[str | None] = mapped_column(String(64), nullable=True) enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) notify_on: Mapped[str] = mapped_column( String(16), nullable=False, default="none" ) # 'none' / 'failure' / 'all' retention_count: Mapped[int] = mapped_column(Integer, nullable=False, default=7) retention_days: Mapped[int | None] = mapped_column(Integer, nullable=True) description: Mapped[str | None] = mapped_column(String(255), nullable=True) storage: Mapped["Storage"] = relationship(lazy="joined") # noqa: F821 created_at: Mapped[datetime] = mapped_column( DateTime, server_default=func.now(), nullable=False ) updated_at: Mapped[datetime] = mapped_column( DateTime, server_default=func.now(), onupdate=func.now(), nullable=False )