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() |