520be53901
- Add proper Alembic initial migration (0001_initial_schema.py) - Migrate refresh tokens from JSON file to SQLite (RefreshTokenTable) - Remove Neko-Sama provider entirely (redirects to Gupy, not a host) - Fix provider health check always showing UNKNOWN - Run check_all_health() on startup - Fix POST /providers/health/check background task bug - Add HTMX refresh after manual health check trigger - Fix anime search relevance scoring with MIN_RELEVANCE_THRESHOLD=0.5 - Replace bare 'except:' with 'except Exception:' across codebase - Add Playwright E2E test suite (12 tests, auth setup, helpers) - Fix toast container blocking clicks via pointer-events: none - Remove obsolete Jest/Vite test files and config - Clean up obsolete test_watchlist scripts - Update sonarr model comment for active providers
70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
"""Database configuration and session management using SQLModel"""
|
|
import os
|
|
from typing import Generator
|
|
from sqlalchemy import create_engine
|
|
from sqlmodel import SQLModel, Session, create_engine
|
|
from app.config import get_settings
|
|
|
|
settings = get_settings()
|
|
|
|
# Database URL can be overridden by environment variable DATABASE_URL
|
|
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./ohm_streaming.db")
|
|
|
|
# Create the engine
|
|
# connect_args={"check_same_thread": False} is required for SQLite and FastAPI
|
|
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
|
|
|
|
|
|
def create_db_and_tables():
|
|
"""Create the database and tables based on the models"""
|
|
# CRITICAL: Import ALL models here to ensure they are registered with SQLModel.metadata
|
|
from app.models.auth import UserTable, RefreshTokenTable
|
|
from app.models.watchlist import WatchlistItemTable, WatchlistSettingsTable
|
|
from app.models.favorites import FavoriteTable
|
|
from app.models.sonarr import SonarrMappingTable, SonarrConfigTable
|
|
from app.models.settings import AppSettingsTable
|
|
|
|
SQLModel.metadata.create_all(engine)
|
|
|
|
# Add new columns to existing tables if they don't exist (SQLite workaround)
|
|
_ensure_columns(engine)
|
|
|
|
|
|
def _ensure_columns(engine):
|
|
"""Add new columns to app_settings table if they don't exist"""
|
|
from sqlalchemy import inspect, text
|
|
|
|
inspector = inspect(engine)
|
|
if 'app_settings' not in inspector.get_table_names():
|
|
return
|
|
|
|
existing = {col['name'] for col in inspector.get_columns('app_settings')}
|
|
|
|
new_columns = {
|
|
'recommendations_filter': 'TEXT DEFAULT "all"',
|
|
'releases_filter': 'TEXT DEFAULT "all"',
|
|
'anime_enabled': 'BOOLEAN DEFAULT 1',
|
|
'series_enabled': 'BOOLEAN DEFAULT 1',
|
|
'download_dir': 'TEXT DEFAULT "downloads"',
|
|
}
|
|
|
|
# Add is_admin to users table if missing
|
|
if 'users' in inspector.get_table_names():
|
|
user_cols = {col['name'] for col in inspector.get_columns('users')}
|
|
if 'is_admin' not in user_cols:
|
|
with engine.connect() as conn:
|
|
conn.execute(text('ALTER TABLE users ADD COLUMN is_admin BOOLEAN DEFAULT 0'))
|
|
conn.commit()
|
|
|
|
with engine.connect() as conn:
|
|
for col_name, col_def in new_columns.items():
|
|
if col_name not in existing:
|
|
conn.execute(text(f'ALTER TABLE app_settings ADD COLUMN {col_name} {col_def}'))
|
|
conn.commit()
|
|
|
|
|
|
def get_session() -> Generator[Session, None, None]:
|
|
"""Dependency for getting a database session"""
|
|
with Session(engine) as session:
|
|
yield session
|