feat: add database models and alembic setup
- SQLAlchemy async models for sources, jobs, schedules, executions, backups, settings - Alembic migration configuration
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
|
||||
from sqlalchemy.orm import declarative_base
|
||||
|
||||
DATABASE_URL = "sqlite+aiosqlite:///./backup_tool.db"
|
||||
|
||||
engine = create_async_engine(DATABASE_URL, echo=True)
|
||||
AsyncSessionLocal = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
async def get_db():
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
await session.close()
|
||||
@@ -0,0 +1,82 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, ForeignKey, JSON
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
from .database import Base
|
||||
|
||||
class Source(Base):
|
||||
__tablename__ = "sources"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String, nullable=False)
|
||||
type = Column(String, nullable=False) # local, ssh, database
|
||||
config = Column(JSON, default=dict)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
jobs = relationship("Job", back_populates="source", cascade="all, delete-orphan")
|
||||
|
||||
class Job(Base):
|
||||
__tablename__ = "jobs"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String, nullable=False)
|
||||
source_id = Column(Integer, ForeignKey("sources.id"), nullable=False)
|
||||
strategy = Column(String, nullable=False, default="full") # full, incremental
|
||||
destination_path = Column(String, nullable=False)
|
||||
exclude_patterns = Column(JSON, default=list)
|
||||
enabled = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
source = relationship("Source", back_populates="jobs")
|
||||
schedule = relationship("Schedule", back_populates="job", uselist=False, cascade="all, delete-orphan")
|
||||
executions = relationship("JobExecution", back_populates="job", cascade="all, delete-orphan")
|
||||
|
||||
class Schedule(Base):
|
||||
__tablename__ = "schedules"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
job_id = Column(Integer, ForeignKey("jobs.id"), unique=True, nullable=False)
|
||||
cron_expression = Column(String, nullable=False)
|
||||
enabled = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
|
||||
job = relationship("Job", back_populates="schedule")
|
||||
|
||||
class JobExecution(Base):
|
||||
__tablename__ = "job_executions"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
|
||||
status = Column(String, nullable=False, default="pending") # pending, running, success, failed, cancelled
|
||||
started_at = Column(DateTime, nullable=True)
|
||||
completed_at = Column(DateTime, nullable=True)
|
||||
bytes_processed = Column(Integer, default=0)
|
||||
bytes_backed_up = Column(Integer, default=0)
|
||||
error_message = Column(Text, nullable=True)
|
||||
triggered_by = Column(String, nullable=False) # manual, schedule
|
||||
|
||||
job = relationship("Job", back_populates="executions")
|
||||
backups = relationship("Backup", back_populates="execution", cascade="all, delete-orphan")
|
||||
|
||||
class Backup(Base):
|
||||
__tablename__ = "backups"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
execution_id = Column(Integer, ForeignKey("job_executions.id"), nullable=False)
|
||||
storage_path = Column(String, nullable=False)
|
||||
size_bytes = Column(Integer, default=0)
|
||||
checksum = Column(String, nullable=True)
|
||||
type = Column(String, nullable=False) # full, incremental
|
||||
parent_backup_id = Column(Integer, ForeignKey("backups.id"), nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
|
||||
execution = relationship("JobExecution", back_populates="backups")
|
||||
parent_backup = relationship("Backup", remote_side=[id])
|
||||
|
||||
class Setting(Base):
|
||||
__tablename__ = "settings"
|
||||
|
||||
key = Column(String, primary_key=True)
|
||||
value = Column(Text, nullable=True)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
Reference in New Issue
Block a user