From 1ef419c03d11fbba21c02535efc5aeba77c4cf41 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Sun, 21 Sep 2025 17:17:13 +0200 Subject: [PATCH] Fixed database name hardcoded --- scripts/backup_database.py | 76 ++++++++++++++++++++++++++++++++------ scripts/verify_setup.py | 76 ++++++++++++++++++++++++++------------ 2 files changed, 117 insertions(+), 35 deletions(-) diff --git a/scripts/backup_database.py b/scripts/backup_database.py index 19cf30c7..52fbfcd1 100644 --- a/scripts/backup_database.py +++ b/scripts/backup_database.py @@ -1,20 +1,48 @@ # scripts/backup_database.py -"""Simple backup for early development.""" +"""Database backup utility that uses project configuration.""" import os +import sys import shutil +import sqlite3 from datetime import datetime from pathlib import Path +from urllib.parse import urlparse + +# Add project root to Python path +sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) + +from app.core.config import settings -def backup_current_db(): - """Quick backup of current database.""" +def get_database_path(): + """Extract database path from DATABASE_URL.""" + db_url = settings.database_url - db_path = "ecommerce.db" + if db_url.startswith('sqlite:///'): + # Remove sqlite:/// prefix and handle relative paths + db_path = db_url.replace('sqlite:///', '') + if db_path.startswith('./'): + db_path = db_path[2:] # Remove ./ prefix + return db_path + else: + # For PostgreSQL or other databases, we can't do file backup + print(f"[INFO] Database type: {db_url.split('://')[0]}") + print("[ERROR] File backup only supported for SQLite databases") + return None + + +def backup_sqlite_database(): + """Backup SQLite database using proper connection.""" + + db_path = get_database_path() + if not db_path: + return False if not os.path.exists(db_path): - print("ℹ️ No existing database found - nothing to backup") - return + print(f"[INFO] No database file found at: {db_path}") + print("[INFO] Nothing to backup") + return True # Create backup directory backup_dir = Path("backups") @@ -22,14 +50,40 @@ def backup_current_db(): # Create timestamped backup timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") - backup_path = backup_dir / f"ecommerce_pre_reset_{timestamp}.db" + backup_path = backup_dir / f"database_backup_{timestamp}.db" try: - shutil.copy2(db_path, backup_path) - print(f"✅ Database backed up to: {backup_path}") + # Use SQLite backup API for better consistency + source_conn = sqlite3.connect(db_path) + backup_conn = sqlite3.connect(str(backup_path)) + + source_conn.backup(backup_conn) + + source_conn.close() + backup_conn.close() + + print(f"[SUCCESS] Database backed up to: {backup_path}") + return True + except Exception as e: - print(f"⚠️ Backup failed: {e}") + print(f"[ERROR] Backup failed: {e}") + return False + + +def backup_database(): + """Main backup function that handles different database types.""" + + print("[BACKUP] Starting database backup...") + print(f"[INFO] Database URL: {settings.database_url}") + + if settings.database_url.startswith('sqlite'): + return backup_sqlite_database() + else: + print("[INFO] For PostgreSQL databases, use pg_dump:") + print(f"pg_dump {settings.database_url} > backup_$(date +%Y%m%d_%H%M%S).sql") + return True if __name__ == "__main__": - backup_current_db() + success = backup_database() + sys.exit(0 if success else 1) diff --git a/scripts/verify_setup.py b/scripts/verify_setup.py index a973ea37..eb68ee97 100644 --- a/scripts/verify_setup.py +++ b/scripts/verify_setup.py @@ -1,37 +1,64 @@ # scripts/verify_setup.py -"""Verify database setup and migration status for complete project structure.""" +"""Verify database setup and migration status using project configuration.""" import os import sys from sqlalchemy import create_engine, text from alembic import command from alembic.config import Config +from urllib.parse import urlparse -# Add project root to Python path (same as alembic does) +# 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 + else: + return db_type, None + def verify_database_setup(): - """Verify database and migration setup.""" + """Verify database and migration setup using config.""" print("[VERIFY] Verifying database setup...") + print(f"[CONFIG] Database URL: {settings.database_url}") print() - # Check if database file exists - db_path = "ecommerce.db" - if not os.path.exists(db_path): - print("[ERROR] Database file not found!") - return False + db_type, db_path = get_database_info() + print(f"[INFO] Database type: {db_type}") - print(f"[OK] Database file exists: {db_path}") + 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 and connect - engine = create_engine('sqlite:///./ecommerce.db') + # Create engine using the configured URL + engine = create_engine(settings.database_url) with engine.connect() as conn: - # Get table list - result = conn.execute(text("SELECT name FROM sqlite_master WHERE type='table'")) + # 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:") @@ -44,9 +71,9 @@ def verify_database_setup(): for table in sorted(tables): if table == 'alembic_version': - print(f" ✓ {table} (migration tracking)") + print(f" * {table} (migration tracking)") elif table in expected_tables: - print(f" ✓ {table}") + print(f" * {table}") else: print(f" ? {table} (unexpected)") @@ -69,6 +96,7 @@ def verify_database_setup(): 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 @@ -124,7 +152,7 @@ def verify_model_structure(): for module in api_modules: try: __import__(f'models.api.{module}') - print(f" ✓ models.api.{module}") + print(f" * models.api.{module}") except ImportError: print(f" ? models.api.{module} (not found, optional)") @@ -152,9 +180,9 @@ def check_project_structure(): for path in critical_paths: if os.path.exists(path): - print(f" ✓ {path}") + print(f" * {path}") else: - print(f" ✗ {path} (missing)") + print(f" X {path} (missing)") # Check __init__.py files init_files = [ @@ -166,9 +194,9 @@ def check_project_structure(): print(f"\n[INIT] Checking __init__.py files...") for init_file in init_files: if os.path.exists(init_file): - print(f" ✓ {init_file}") + print(f" * {init_file}") else: - print(f" ✗ {init_file} (missing - will cause import issues)") + print(f" X {init_file} (missing - will cause import issues)") if __name__ == "__main__": @@ -183,11 +211,11 @@ if __name__ == "__main__": if success: print() - print("[READY] 🎉 Your complete project structure is ready!") + 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("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")