Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 8,901 Bytes
46db677 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
#!/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() |