From 2575e0c12a7bb73c4345bff1f10e73923a94d6d2 Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 31 Oct 2025 18:41:38 -0400 Subject: [PATCH] fix: add database schema migration for simulation_run_id column Add automatic schema migration to handle existing databases that don't have the simulation_run_id column in the positions table. Problem: - v0.3.0-alpha.3 databases lack simulation_run_id column - CREATE TABLE IF NOT EXISTS doesn't add new columns to existing tables - Index creation fails with "no such column: simulation_run_id" Solution: - Add _migrate_schema() function to detect and migrate old schemas - Check if positions table exists and inspect its columns - ALTER TABLE to add simulation_run_id if missing - Run migration before creating indexes This allows seamless upgrades from alpha.3 to alpha.4 without manual database deletion or migration scripts. Fixes docker compose startup error: sqlite3.OperationalError: no such column: simulation_run_id Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- api/database.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api/database.py b/api/database.py index 86aa34c..d1fe94c 100644 --- a/api/database.py +++ b/api/database.py @@ -203,6 +203,9 @@ def initialize_database(db_path: str = "data/jobs.db") -> None: ) """) + # Run schema migrations for existing databases + _migrate_schema(cursor) + # Create indexes for performance _create_indexes(cursor) @@ -210,6 +213,21 @@ def initialize_database(db_path: str = "data/jobs.db") -> None: conn.close() +def _migrate_schema(cursor: sqlite3.Cursor) -> None: + """Migrate existing database schema to latest version.""" + # Check if positions table exists and has simulation_run_id column + cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='positions'") + if cursor.fetchone(): + cursor.execute("PRAGMA table_info(positions)") + columns = [row[1] for row in cursor.fetchall()] + + if 'simulation_run_id' not in columns: + # Add simulation_run_id column to existing positions table + cursor.execute(""" + ALTER TABLE positions ADD COLUMN simulation_run_id TEXT + """) + + def _create_indexes(cursor: sqlite3.Cursor) -> None: """Create database indexes for query performance."""