Alembic configuration

This commit is contained in:
2025-09-21 13:08:38 +02:00
parent c2a1056db7
commit b47c88b24b
3 changed files with 95 additions and 46 deletions

View File

@@ -1,10 +1,11 @@
# app/core/lifespan.py # app/core/lifespan.py
"""Summary description .... """Application lifespan management - Clean Migration Approach.
This module provides classes and functions for: This module provides classes and functions for:
- .... - Application startup and shutdown events
- .... - Logging setup
- .... - Default user creation
- NO database table creation (handled by Alembic)
""" """
import logging import logging
@@ -14,7 +15,7 @@ from fastapi import FastAPI
from sqlalchemy import text from sqlalchemy import text
from middleware.auth import AuthManager from middleware.auth import AuthManager
from models.database.base import Base # Remove this import if not needed: from models.database.base import Base
from .database import SessionLocal, engine from .database import SessionLocal, engine
from .logging import setup_logging from .logging import setup_logging
@@ -25,62 +26,106 @@ auth_manager = AuthManager()
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
"""Application lifespan events.""" """Application lifespan events - Clean migration approach."""
# Startup
app_logger = setup_logging() # Configure logging first # === STARTUP ===
app_logger = setup_logging()
app_logger.info("Starting up ecommerce API") app_logger.info("Starting up ecommerce API")
# Create tables # === REMOVED: Database table creation ===
Base.metadata.create_all(bind=engine) # Base.metadata.create_all(bind=engine) # ❌ Removed - handled by Alembic
# create_indexes() # ❌ Removed - handled by Alembic
# Create indexes # === KEPT: Application-level initialization ===
create_indexes()
# Create default admin user # Create default admin user (after migrations have run)
db = SessionLocal() db = SessionLocal()
try: try:
auth_manager.create_default_admin_user(db) auth_manager.create_default_admin_user(db)
logger.info("Default admin user initialization completed")
except Exception as e: except Exception as e:
logger.error(f"Failed to create default admin user: {e}") logger.error(f"Failed to create default admin user: {e}")
# In development, this might fail if tables don't exist yet
# That's OK - migrations should be run separately
finally: finally:
db.close() db.close()
# Add any other application-level initialization here
# Examples:
# - Load configuration
# - Initialize caches
# - Set up external service connections
# - Load initial data (AFTER migrations)
logger.info("✅ Application startup completed")
yield yield
# Shutdown # === SHUTDOWN ===
app_logger.info("Shutting down ecommerce API") app_logger.info("Shutting down ecommerce API")
# Add cleanup tasks here if needed
def create_indexes(): # === REMOVED FUNCTION ===
"""Create database indexes.""" # def create_indexes():
with engine.connect() as conn: # """Create database indexes."""
try: # # This is now handled by Alembic migrations
# User indexes # pass
conn.execute(
text("CREATE INDEX IF NOT EXISTS idx_user_email ON users(email)")
)
conn.execute(
text("CREATE INDEX IF NOT EXISTS idx_user_username ON users(username)")
)
# Product indexes
conn.execute(
text("CREATE INDEX IF NOT EXISTS idx_product_gtin ON products(gtin)")
)
conn.execute(
text(
"CREATE INDEX IF NOT EXISTS idx_product_marketplace ON products(marketplace)"
)
)
# Stock indexes # === NEW HELPER FUNCTION ===
conn.execute( def check_database_ready():
text( """Check if database is ready (migrations have been run)."""
"CREATE INDEX IF NOT EXISTS idx_stock_gtin_location ON stock(gtin, location)" try:
) with engine.connect() as conn:
) # Try to query a table that should exist
result = conn.execute(text("SELECT name FROM sqlite_master WHERE type='table' LIMIT 1"))
tables = result.fetchall()
return len(tables) > 0
except Exception:
return False
conn.commit()
logger.info("Database indexes created successfully") def get_migration_status():
except Exception as e: """Get current Alembic migration status."""
logger.warning(f"Index creation warning: {e}") try:
from alembic import command
from alembic.config import Config
alembic_cfg = Config("alembic.ini")
# This would need more implementation to actually check status
# For now, just return a placeholder
return "Migration status check not implemented"
except Exception as e:
logger.warning(f"Could not check migration status: {e}")
return "Unknown"
# === STARTUP VERIFICATION (Optional) ===
def verify_startup_requirements():
"""Verify that all startup requirements are met."""
issues = []
# Check if database exists and has tables
if not check_database_ready():
issues.append("Database not ready - run 'make migrate-up' first")
# Add other checks as needed
# - Configuration validation
# - External service connectivity
# - Required environment variables
if issues:
logger.error("❌ Startup verification failed:")
for issue in issues:
logger.error(f" - {issue}")
return False
logger.info("✅ Startup verification passed")
return True
# You can call this in your main.py if desired:
# if not verify_startup_requirements():
# raise RuntimeError("Application startup requirements not met")

View File

@@ -1,9 +1,11 @@
# Database migrations
alembic>=1.13.0
# Linting and formatting tools # Linting and formatting tools
# Development tools
black>=23.0.0 black>=23.0.0
isort>=5.12.0 isort>=5.12.0
flake8>=6.0.0 flake8>=6.0.0
mypy>=1.0.0 mypy>=1.5.0
# Optional: More advanced linting # Optional: More advanced linting
flake8-docstrings>=1.7.0 flake8-docstrings>=1.7.0

View File

@@ -1,3 +1,5 @@
# Database migrations
alembic>=1.13.0
starlette==0.27.0 starlette==0.27.0
# requirements.txt # requirements.txt
# Core FastAPI and web framework # Core FastAPI and web framework