Update remaining application code to use canonical module locations: - app/services/letzshop/order_service.py - app/services/platform_health_service.py - alembic/env.py (inventory and order models) - scripts/investigate_order.py, verify_setup.py, seed_demo.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
255 lines
7.7 KiB
Python
255 lines
7.7 KiB
Python
# 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)
|