Files
mikrotik_backup_system/backend/app/db/session.py
Mateusz Gruszczyński 3da6c2832c first commit
2026-04-14 11:39:46 +02:00

85 lines
3.5 KiB
Python

from pathlib import Path
from sqlalchemy import create_engine, inspect, text
from sqlalchemy.orm import declarative_base, sessionmaker
from app.core.config import settings
from app.core.security import get_password_hash
def _ensure_sqlite_parent(database_url: str) -> None:
if not database_url.startswith('sqlite:///'):
return
relative_path = database_url.removeprefix('sqlite:///')
if not relative_path or relative_path == ':memory:':
return
db_path = Path(relative_path)
if not db_path.is_absolute():
db_path = Path.cwd() / db_path
db_path.parent.mkdir(parents=True, exist_ok=True)
_ensure_sqlite_parent(settings.database_url)
engine = create_engine(
settings.database_url,
connect_args={'check_same_thread': False} if settings.database_url.startswith('sqlite') else {},
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def _ensure_column(table_name: str, column_name: str, ddl: str) -> None:
inspector = inspect(engine)
existing = {column['name'] for column in inspector.get_columns(table_name)}
if column_name in existing:
return
with engine.begin() as connection:
connection.execute(text(f'ALTER TABLE {table_name} ADD COLUMN {column_name} {ddl}'))
def _run_lightweight_migrations() -> None:
tables = set(inspect(engine).get_table_names())
if 'global_settings' in tables:
_ensure_column('global_settings', 'connection_test_interval_minutes', 'INTEGER DEFAULT 0')
_ensure_column('global_settings', 'default_switchos_username', 'VARCHAR(120)')
_ensure_column('global_settings', 'default_switchos_password', 'VARCHAR(255)')
if 'users' in tables:
_ensure_column('users', 'preferred_language', "VARCHAR(8) DEFAULT 'pl' NOT NULL")
_ensure_column('users', 'preferred_font', "VARCHAR(32) DEFAULT 'default' NOT NULL")
if 'routers' in tables:
_ensure_column('routers', 'device_type', "VARCHAR(32) DEFAULT 'routeros' NOT NULL")
_ensure_column('routers', 'last_connection_status', 'BOOLEAN')
_ensure_column('routers', 'last_connection_tested_at', 'DATETIME')
_ensure_column('routers', 'last_connection_error', 'TEXT')
_ensure_column('routers', 'last_connection_hostname', 'VARCHAR(255)')
_ensure_column('routers', 'last_connection_model', 'VARCHAR(255)')
_ensure_column('routers', 'last_connection_version', 'VARCHAR(255)')
_ensure_column('routers', 'last_connection_uptime', 'VARCHAR(255)')
_ensure_column('routers', 'last_connection_transport', 'VARCHAR(32)')
_ensure_column('routers', 'last_connection_server', 'VARCHAR(255)')
_ensure_column('routers', 'last_connection_auth_mode', 'VARCHAR(64)')
_ensure_column('routers', 'last_connection_http_status', 'VARCHAR(32)')
_ensure_column('routers', 'last_connection_backup_available', 'BOOLEAN')
def init_db():
import app.db.base # noqa: F401
from app.models.settings import GlobalSettings
from app.models.user import User
Base.metadata.create_all(bind=engine)
_run_lightweight_migrations()
with SessionLocal() as db:
if not db.query(User).first():
db.add(
User(
username=settings.default_admin_username,
password_hash=get_password_hash(settings.default_admin_password),
)
)
db.commit()
if not db.query(GlobalSettings).first():
db.add(GlobalSettings())
db.commit()