Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| #!/usr/bin/env python3 | |
| """ | |
| Production database initialization script. | |
| This ensures templates are populated properly and verifies database health. | |
| SAFE for PostgreSQL/RDS - only creates tables on SQLite databases. | |
| """ | |
| import sys | |
| import os | |
| import logging | |
| from datetime import datetime, UTC | |
| # Add the project root to the Python path | |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from src.db.init_db import init_db, session_factory, engine, is_postgres_db | |
| from src.db.schemas.models import Base, AgentTemplate, UserTemplatePreference | |
| from scripts.populate_agent_templates import populate_templates | |
| from sqlalchemy import inspect, text | |
| from src.utils.logger import Logger | |
| logger = Logger("init_production_db", see_time=True, console_log=True) | |
| def get_database_type(): | |
| """Get the database type (sqlite or postgresql).""" | |
| try: | |
| if is_postgres_db(): | |
| return "postgresql" | |
| else: | |
| return "sqlite" | |
| except Exception as e: | |
| logger.log_message(f"Error determining database type: {e}", logging.ERROR) | |
| return "unknown" | |
| def check_table_exists(table_name: str) -> bool: | |
| """Check if a table exists in the database.""" | |
| try: | |
| inspector = inspect(engine) | |
| tables = inspector.get_table_names() | |
| return table_name in tables | |
| except Exception as e: | |
| logger.log_message(f"Error checking table existence: {e}", logging.ERROR) | |
| return False | |
| def verify_database_schema(): | |
| """Verify that all required tables exist. Only create tables on SQLite.""" | |
| db_type = get_database_type() | |
| logger.log_message(f"π Verifying database schema for {db_type.upper()} database...", logging.INFO) | |
| required_tables = [ | |
| 'users', 'chats', 'messages', 'model_usage', 'code_executions', | |
| 'message_feedback', 'deep_analysis_reports', 'agent_templates', | |
| 'user_template_preferences' | |
| ] | |
| missing_tables = [] | |
| existing_tables = [] | |
| for table in required_tables: | |
| if not check_table_exists(table): | |
| missing_tables.append(table) | |
| logger.log_message(f"β Missing table: {table}", logging.WARNING) | |
| else: | |
| existing_tables.append(table) | |
| logger.log_message(f"β Table exists: {table}", logging.INFO) | |
| if missing_tables: | |
| if db_type == "sqlite": | |
| logger.log_message(f"π§ Creating missing tables on SQLite: {missing_tables}", logging.INFO) | |
| try: | |
| # Safe to create tables on SQLite | |
| Base.metadata.create_all(engine) | |
| logger.log_message("β All tables created successfully on SQLite", logging.INFO) | |
| except Exception as e: | |
| logger.log_message(f"β Failed to create tables: {e}", logging.ERROR) | |
| raise | |
| else: | |
| # PostgreSQL/RDS - DO NOT create tables automatically | |
| logger.log_message(f"β οΈ WARNING: Missing tables detected in {db_type.upper()} database: {missing_tables}", logging.WARNING) | |
| logger.log_message("π‘οΈ SAFETY: Not creating tables automatically on PostgreSQL/RDS", logging.INFO) | |
| logger.log_message("π Please ensure these tables exist in your RDS database:", logging.INFO) | |
| for table in missing_tables: | |
| logger.log_message(f" - {table}", logging.INFO) | |
| # Continue without failing - the app might still work with existing tables | |
| if 'agent_templates' in missing_tables or 'user_template_preferences' in missing_tables: | |
| logger.log_message("β οΈ Template functionality may not work without agent_templates and user_template_preferences tables", logging.WARNING) | |
| else: | |
| logger.log_message(f"β All required tables exist in {db_type.upper()} database", logging.INFO) | |
| def verify_template_data(): | |
| """Verify that agent templates are populated. Safe for all database types.""" | |
| logger.log_message("π Verifying template data...", logging.INFO) | |
| session = session_factory() | |
| try: | |
| # Check if agent_templates table exists before querying | |
| if not check_table_exists('agent_templates'): | |
| logger.log_message("β οΈ agent_templates table does not exist, skipping template verification", logging.WARNING) | |
| return | |
| template_count = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).count() | |
| logger.log_message(f"π Found {template_count} active templates", logging.INFO) | |
| if template_count == 0: | |
| logger.log_message("π§ No templates found, populating...", logging.INFO) | |
| try: | |
| populate_templates() | |
| # Verify population worked | |
| new_count = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).count() | |
| logger.log_message(f"β Templates populated. Total active templates: {new_count}", logging.INFO) | |
| except Exception as e: | |
| logger.log_message(f"β Template population failed: {e}", logging.ERROR) | |
| logger.log_message("β οΈ App will continue but template functionality may not work", logging.WARNING) | |
| else: | |
| logger.log_message("β Templates already populated", logging.INFO) | |
| except Exception as e: | |
| logger.log_message(f"β Error verifying templates: {e}", logging.ERROR) | |
| logger.log_message("β οΈ Template verification failed, but app will continue", logging.WARNING) | |
| finally: | |
| session.close() | |
| def test_template_api_functionality(): | |
| """Test that template-related database operations work. Safe for all database types.""" | |
| logger.log_message("π§ͺ Testing template API functionality...", logging.INFO) | |
| session = session_factory() | |
| try: | |
| # Check if agent_templates table exists before testing | |
| if not check_table_exists('agent_templates'): | |
| logger.log_message("β οΈ agent_templates table does not exist, skipping API test", logging.WARNING) | |
| return | |
| # Test basic template query | |
| templates = session.query(AgentTemplate).filter(AgentTemplate.is_active == True).limit(5).all() | |
| logger.log_message(f"β Successfully queried {len(templates)} templates", logging.INFO) | |
| if templates: | |
| sample_template = templates[0] | |
| logger.log_message(f"π Sample template: {sample_template.template_name} - {sample_template.display_name}", logging.INFO) | |
| else: | |
| logger.log_message("π No templates found in database", logging.INFO) | |
| except Exception as e: | |
| logger.log_message(f"β Template API test failed: {e}", logging.ERROR) | |
| logger.log_message("β οΈ Template API may not work properly", logging.WARNING) | |
| finally: | |
| session.close() | |
| def run_safe_initialization(): | |
| """Run safe database initialization that respects production databases.""" | |
| db_type = get_database_type() | |
| logger.log_message(f"π Starting SAFE database initialization for {db_type.upper()}...", logging.INFO) | |
| if db_type == "postgresql": | |
| logger.log_message("π‘οΈ PostgreSQL/RDS detected - running in SAFE mode", logging.INFO) | |
| logger.log_message("π Will only verify schema and populate templates", logging.INFO) | |
| elif db_type == "sqlite": | |
| logger.log_message("π½ SQLite detected - full initialization mode", logging.INFO) | |
| try: | |
| # Step 1: Initialize database (safe for all types) | |
| logger.log_message("Step 1: Basic database initialization", logging.INFO) | |
| if db_type == "sqlite": | |
| init_db() # Only run full init on SQLite | |
| else: | |
| logger.log_message("Skipping init_db() for PostgreSQL (safety)", logging.INFO) | |
| # Step 2: Verify schema (safe - only creates tables on SQLite) | |
| logger.log_message("Step 2: Schema verification", logging.INFO) | |
| verify_database_schema() | |
| # Step 3: Verify template data (safe for all types) | |
| logger.log_message("Step 3: Template data verification", logging.INFO) | |
| verify_template_data() | |
| # Step 4: Test functionality (safe for all types) | |
| logger.log_message("Step 4: Functionality testing", logging.INFO) | |
| test_template_api_functionality() | |
| logger.log_message(f"π Safe database initialization completed for {db_type.upper()}!", logging.INFO) | |
| except Exception as e: | |
| logger.log_message(f"π₯ Database initialization failed: {e}", logging.ERROR) | |
| logger.log_message("β οΈ App may still start but some features might not work", logging.WARNING) | |
| # Don't raise - let the app try to start anyway | |
| if __name__ == "__main__": | |
| run_safe_initialization() |