85 lines
3.5 KiB
Python
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()
|