From 45cd1e12b67d59b8fb9955acb6b2fd6a3afb3caf Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 4 Nov 2025 10:26:00 -0500 Subject: [PATCH] feat: drop old schema tables (trading_sessions, positions, reasoning_logs) - Created migration script to drop old tables - Removed old table creation from database.py - Added tests to verify old tables are removed and new tables exist - Migration script can be run standalone with: PYTHONPATH=. python api/migrations/002_drop_old_schema.py --- api/database.py | 36 +++-------------------- api/migrations/002_drop_old_schema.py | 42 +++++++++++++++++++++++++++ tests/unit/test_old_schema_removed.py | 42 +++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 32 deletions(-) create mode 100644 api/migrations/002_drop_old_schema.py create mode 100644 tests/unit/test_old_schema_removed.py diff --git a/api/database.py b/api/database.py index e8468b7..a55f5cb 100644 --- a/api/database.py +++ b/api/database.py @@ -156,38 +156,10 @@ def initialize_database(db_path: str = "data/jobs.db") -> None: # ) # """) - # Table 5: Trading Sessions - One per model-day trading session - cursor.execute(""" - CREATE TABLE IF NOT EXISTS trading_sessions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - job_id TEXT NOT NULL, - date TEXT NOT NULL, - model TEXT NOT NULL, - session_summary TEXT, - started_at TEXT NOT NULL, - completed_at TEXT, - total_messages INTEGER, - FOREIGN KEY (job_id) REFERENCES jobs(job_id) ON DELETE CASCADE, - UNIQUE(job_id, date, model) - ) - """) - - # Table 6: Reasoning Logs - AI decision logs linked to sessions - cursor.execute(""" - CREATE TABLE IF NOT EXISTS reasoning_logs ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - session_id INTEGER NOT NULL, - message_index INTEGER NOT NULL, - role TEXT NOT NULL CHECK(role IN ('user', 'assistant', 'tool')), - content TEXT NOT NULL, - summary TEXT, - tool_name TEXT, - tool_input TEXT, - timestamp TEXT NOT NULL, - FOREIGN KEY (session_id) REFERENCES trading_sessions(id) ON DELETE CASCADE, - UNIQUE(session_id, message_index) - ) - """) + # OLD TABLES REMOVED: + # - trading_sessions → replaced by trading_days + # - reasoning_logs → replaced by trading_days.reasoning_full (JSON column) + # See api/migrations/002_drop_old_schema.py for removal migration # Table 7: Tool Usage - Tool usage statistics cursor.execute(""" diff --git a/api/migrations/002_drop_old_schema.py b/api/migrations/002_drop_old_schema.py new file mode 100644 index 0000000..74f824b --- /dev/null +++ b/api/migrations/002_drop_old_schema.py @@ -0,0 +1,42 @@ +"""Drop old schema tables (trading_sessions, positions, reasoning_logs).""" + + +def drop_old_schema(db): + """ + Drop old schema tables that have been replaced by new schema. + + Old schema: + - trading_sessions → replaced by trading_days + - positions (action-centric) → replaced by trading_days + actions + holdings + - reasoning_logs → replaced by trading_days.reasoning_full + + Args: + db: Database instance + """ + + # Drop reasoning_logs (child table first) + db.connection.execute("DROP TABLE IF EXISTS reasoning_logs") + + # Drop positions (note: this is the OLD action-centric positions table) + # The new schema doesn't have a positions table at all + db.connection.execute("DROP TABLE IF EXISTS positions") + + # Drop trading_sessions + db.connection.execute("DROP TABLE IF EXISTS trading_sessions") + + db.connection.commit() + + print("✅ Dropped old schema tables: trading_sessions, positions, reasoning_logs") + + +if __name__ == "__main__": + """Run migration standalone.""" + from api.database import Database + from tools.deployment_config import get_db_path + + db_path = get_db_path("data/trading.db") + db = Database(db_path) + + drop_old_schema(db) + + print(f"✅ Migration complete: {db_path}") diff --git a/tests/unit/test_old_schema_removed.py b/tests/unit/test_old_schema_removed.py new file mode 100644 index 0000000..1758517 --- /dev/null +++ b/tests/unit/test_old_schema_removed.py @@ -0,0 +1,42 @@ +"""Verify old schema tables are removed.""" + +import pytest +from api.database import Database + + +def test_old_tables_do_not_exist(): + """Verify trading_sessions, old positions, reasoning_logs don't exist.""" + + db = Database(":memory:") + + # Query sqlite_master for old tables + cursor = db.connection.execute(""" + SELECT name FROM sqlite_master + WHERE type='table' AND name IN ( + 'trading_sessions', 'reasoning_logs' + ) + """) + + tables = cursor.fetchall() + + assert len(tables) == 0, f"Old tables should not exist, found: {tables}" + + +def test_new_tables_exist(): + """Verify new schema tables exist.""" + + db = Database(":memory:") + + cursor = db.connection.execute(""" + SELECT name FROM sqlite_master + WHERE type='table' AND name IN ( + 'trading_days', 'holdings', 'actions' + ) + ORDER BY name + """) + + tables = [row[0] for row in cursor.fetchall()] + + assert 'trading_days' in tables + assert 'holdings' in tables + assert 'actions' in tables