first commit
This commit is contained in:
84
backend/app/db/session.py
Normal file
84
backend/app/db/session.py
Normal file
@@ -0,0 +1,84 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user