"""Database migration utilities. This module provides utilities for database migrations and schema versioning. Alembic integration can be added when needed for production environments. For now, we use SQLAlchemy's create_all for automatic schema creation. """ from __future__ import annotations import logging from typing import Optional from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncEngine from src.server.database.base import Base from src.server.database.connection import get_engine, get_sync_engine logger = logging.getLogger(__name__) async def initialize_schema(engine: Optional[AsyncEngine] = None) -> None: """Initialize database schema. Creates all tables defined in Base metadata if they don't exist. This is a simple migration strategy suitable for single-instance deployments. For production with multiple instances, consider using Alembic: - alembic init alembic - alembic revision --autogenerate -m "Initial schema" - alembic upgrade head Args: engine: Optional database engine (uses default if not provided) Raises: RuntimeError: If database is not initialized """ if engine is None: engine = get_engine() logger.info("Initializing database schema...") # Create all tables async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) logger.info("Database schema initialized successfully") async def check_schema_version(engine: Optional[AsyncEngine] = None) -> str: """Check current database schema version. Returns a simple version identifier based on existing tables. For production, consider using Alembic for proper versioning. Args: engine: Optional database engine (uses default if not provided) Returns: Schema version string Raises: RuntimeError: If database is not initialized """ if engine is None: engine = get_engine() async with engine.connect() as conn: # Check which tables exist result = await conn.execute( text( "SELECT name FROM sqlite_master " "WHERE type='table' AND name NOT LIKE 'sqlite_%'" ) ) tables = [row[0] for row in result] if not tables: return "empty" elif len(tables) == 4 and all( t in tables for t in [ "anime_series", "episodes", "download_queue", "user_sessions", ] ): return "v1.0" else: return "custom" def get_migration_info() -> str: """Get information about database migration setup. Returns: Migration setup information """ return """ Database Migration Information ============================== Current Strategy: SQLAlchemy create_all() - Automatically creates tables on startup - Suitable for development and single-instance deployments - Schema changes require manual handling For Production Migrations (Alembic): ==================================== 1. Initialize Alembic: alembic init alembic 2. Configure alembic/env.py: - Import Base from src.server.database.base - Set target_metadata = Base.metadata 3. Configure alembic.ini: - Set sqlalchemy.url to your database URL 4. Generate initial migration: alembic revision --autogenerate -m "Initial schema" 5. Apply migrations: alembic upgrade head 6. For future changes: - Modify models in src/server/database/models.py - Generate migration: alembic revision --autogenerate -m "Description" - Review generated migration in alembic/versions/ - Apply: alembic upgrade head Benefits of Alembic: - Version control for database schema - Automatic migration generation from model changes - Rollback support with downgrade scripts - Multi-instance deployment support - Safe schema changes in production """ # ============================================================================= # Future Alembic Integration # ============================================================================= # # When ready to use Alembic, follow these steps: # # 1. Install Alembic (already in requirements.txt): # pip install alembic # # 2. Initialize Alembic from project root: # alembic init alembic # # 3. Update alembic/env.py to use our Base: # from src.server.database.base import Base # target_metadata = Base.metadata # # 4. Configure alembic.ini with DATABASE_URL from settings # # 5. Generate initial migration: # alembic revision --autogenerate -m "Initial schema" # # 6. Review generated migration and apply: # alembic upgrade head # # =============================================================================