From fb32bb12c54e9f0311506a80e9b6dd3de42ff824 Mon Sep 17 00:00:00 2001 From: Bill Date: Sun, 2 Nov 2025 19:24:19 -0500 Subject: [PATCH] fix: check column existence before creating indexes Fixes startup error 'no such column: session_id' that occurs when _create_indexes() tries to create indexes on columns that don't exist yet. The issue occurred when initializing a database from scratch: 1. _migrate_schema() adds session_id column to positions table 2. _create_indexes() tries to create index on session_id 3. But on fresh databases, positions table was created without session_id 4. Migration runs after table creation, before index creation 5. Index creation fails because column doesn't exist yet Solution: Check if columns exist before creating indexes on them. This ensures the database can be initialized both: - Fresh (CREATE TABLE without session_id, then ALTER TABLE, then CREATE INDEX) - Migrated (ALTER TABLE adds column, then CREATE INDEX) Tested: All 21 database tests passing --- api/database.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/api/database.py b/api/database.py index 96fd427..8973bf3 100644 --- a/api/database.py +++ b/api/database.py @@ -438,12 +438,19 @@ def _create_indexes(cursor: sqlite3.Cursor) -> None: """) # Positions table - add index for simulation_run_id and session_id - cursor.execute(""" - CREATE INDEX IF NOT EXISTS idx_positions_run_id ON positions(simulation_run_id) - """) - cursor.execute(""" - CREATE INDEX IF NOT EXISTS idx_positions_session_id ON positions(session_id) - """) + # Check if columns exist before creating indexes + cursor.execute("PRAGMA table_info(positions)") + position_columns = [row[1] for row in cursor.fetchall()] + + if 'simulation_run_id' in position_columns: + cursor.execute(""" + CREATE INDEX IF NOT EXISTS idx_positions_run_id ON positions(simulation_run_id) + """) + + if 'session_id' in position_columns: + cursor.execute(""" + CREATE INDEX IF NOT EXISTS idx_positions_session_id ON positions(session_id) + """) def drop_all_tables(db_path: str = "data/jobs.db") -> None: