# scripts/verify_setup.py """Verify database setup and migration status using project configuration.""" import os import sys from urllib.parse import urlparse from alembic.config import Config from sqlalchemy import create_engine, text from alembic import command # Add project root to Python path sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from app.core.config import settings def get_database_info(): """Get database type and path from configuration.""" db_url = settings.database_url parsed = urlparse(db_url) db_type = parsed.scheme if db_type == "sqlite": # Extract path from sqlite:///./path or sqlite:///path db_path = db_url.replace("sqlite:///", "") if db_path.startswith("./"): db_path = db_path[2:] return db_type, db_path return db_type, None def verify_database_setup(): """Verify database and migration setup using config.""" print("[VERIFY] Verifying database setup...") print(f"[CONFIG] Database URL: {settings.database_url}") print() db_type, db_path = get_database_info() print(f"[INFO] Database type: {db_type}") if db_type == "sqlite": if not os.path.exists(db_path): print(f"[ERROR] Database file not found: {db_path}") return False print(f"[OK] Database file exists: {db_path}") else: print(f"[INFO] Using {db_type} database (connection will be tested)") try: # Create engine using the configured URL engine = create_engine(settings.database_url) with engine.connect() as conn: # Get table list (works for both SQLite and PostgreSQL) if db_type == "sqlite": result = conn.execute( text("SELECT name FROM sqlite_master WHERE type='table'") ) else: result = conn.execute( text("SELECT tablename FROM pg_tables WHERE schemaname='public'") ) tables = [row[0] for row in result.fetchall()] print(f"[OK] Found {len(tables)} tables:") # Expected tables from your models expected_tables = [ "users", "products", "inventory", "vendors", "products", "marketplace_import_jobs", "alembic_version", ] for table in sorted(tables): if table == "alembic_version": print(f" * {table} (migration tracking)") elif table in expected_tables: print(f" * {table}") else: print(f" ? {table} (unexpected)") # Check for missing expected tables missing_tables = set(expected_tables) - set(tables) - {"alembic_version"} if missing_tables: print(f"[WARNING] Missing expected tables: {missing_tables}") # Check if alembic_version table exists if "alembic_version" in tables: result = conn.execute(text("SELECT version_num FROM alembic_version")) version = result.fetchone() if version: print(f"[OK] Migration version: {version[0]}") else: print("[WARNING] No migration version recorded") else: print("[ERROR] No alembic_version table - migrations not initialized") return False except Exception as e: print(f"[ERROR] Database connection failed: {e}") print("[HINT] Check your DATABASE_URL in .env file") return False # Check Alembic configuration try: alembic_cfg = Config("alembic.ini") print("[OK] Alembic configuration found") # Try to get current migration print() print("[MIGRATE] Current migration status:") command.current(alembic_cfg, verbose=True) except Exception as e: print(f"[ERROR] Alembic configuration issue: {e}") return False print() print("[SUCCESS] Database setup verification completed!") return True def verify_model_structure(): """Verify both database and API model structure.""" print("[MODELS] Verifying model structure...") # Test database models try: from models.database.base import Base print("[OK] Database Base imported") print( f"[INFO] Found {len(Base.metadata.tables)} database tables: {list(Base.metadata.tables.keys())}" ) # Import specific models from app.modules.inventory.models import Inventory from models.database.marketplace_import_job import MarketplaceImportJob from models.database.marketplace_product import MarketplaceProduct from models.database.product import Product from models.database.user import User from models.database.vendor import Vendor print("[OK] All database models imported successfully") except ImportError as e: print(f"[ERROR] Database model import failed: {e}") return False # Test API models try: import models.schema print("[OK] API models package imported") # Test specific API model imports api_modules = [ "base", "auth", "product", "inventory", "vendor ", "marketplace", "admin", "stats", ] for module in api_modules: try: __import__(f"models.api.{module}") print(f" * models.api.{module}") except ImportError: print(f" ? models.api.{module} (not found, optional)") except ImportError as e: print(f"[WARNING] API models import issue: {e}") # This is not critical for database operations return True def check_project_structure(): """Check overall project structure.""" print("\n[STRUCTURE] Checking project structure...") critical_paths = [ "models/database/base.py", "models/database/user.py", "models/database/marketplace_products.py", "models/database/inventory.py", "app/core/config.py", "alembic/env.py", "alembic.ini", ] for path in critical_paths: if os.path.exists(path): print(f" * {path}") else: print(f" X {path} (missing)") # Check __init__.py files init_files = [ "models/__init__.py", "models/database/__init__.py", "models/api/__init__.py", ] print("\n[INIT] Checking __init__.py files...") for init_file in init_files: if os.path.exists(init_file): print(f" * {init_file}") else: print(f" X {init_file} (missing - will cause import issues)") if __name__ == "__main__": success = True check_project_structure() if verify_model_structure(): success = verify_database_setup() else: success = False if success: print() print("[READY] Your complete project structure is ready!") print() print("Database models: * SQLAlchemy models for data storage") print("API models: * Pydantic models for request/response validation") print("Migrations: * Alembic managing database schema") print() print("Next steps:") print(" 1. Run 'make dev' to start your FastAPI server") print(" 2. Visit http://localhost:8000/docs for interactive API docs") print( " 3. Use your API endpoints for authentication, products, inventory, etc." ) sys.exit(0) else: print() print("[FAILED] Project setup has issues that need to be resolved!") sys.exit(1)