feat: DB-first architecture with lock-safe writes
- price_monitor: writes live prices to both JSON and mofin.db (holdings + live_prices + portfolio_summary) - mofin_db: added execute_with_retry/commit_with_retry with exponential backoff on 'database is locked' - mofin_db: increased timeout 5s->15s, added PRAGMA busy_timeout=15000 - price_monitor retry loop: fixed break-before-if-ok bug (was not retrying on write failure) - DB connection: WAL mode + retry decorator for all write operations - cash sync: preserves DB authoritative cash (JSON cash not pushed to DB) This is the DB-first version. JSON writes remain for dashboard compatibility. Next step: remove JSON writes entirely for full DB-only architecture.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"""Fix: unify todos table schema across project and real DB"""
|
||||
import sqlite3
|
||||
|
||||
project_db = '/home/hmo/projects/MoFin/data/mofin.db'
|
||||
real_db = '/home/hmo/web-dashboard/data/mofin.db'
|
||||
|
||||
# Zhiwei's canonical schema (from project db)
|
||||
target_schema = """
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT DEFAULT 'pending',
|
||||
priority TEXT DEFAULT 'medium',
|
||||
source TEXT DEFAULT 'manual',
|
||||
fix_action TEXT,
|
||||
retry_count INTEGER DEFAULT 0,
|
||||
note TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
"""
|
||||
|
||||
def ensure_todos(db_path, label):
|
||||
db = sqlite3.connect(db_path)
|
||||
existing = db.execute("SELECT name FROM sqlite_master WHERE name='todos'").fetchone()
|
||||
if not existing:
|
||||
db.execute(f"CREATE TABLE todos ({target_schema})")
|
||||
print(f"{label}: created todos table")
|
||||
else:
|
||||
# Ensure all columns exist
|
||||
existing_cols = {r[1] for r in db.execute("PRAGMA table_info(todos)")}
|
||||
needed = {'title', 'description', 'status', 'priority', 'source', 'fix_action',
|
||||
'retry_count', 'note', 'created_at', 'updated_at'}
|
||||
missing = needed - existing_cols
|
||||
for col in missing:
|
||||
if col in ('retry_count',):
|
||||
db.execute(f"ALTER TABLE todos ADD COLUMN {col} INTEGER DEFAULT 0")
|
||||
elif col in ('created_at', 'updated_at'):
|
||||
db.execute(f"ALTER TABLE todos ADD COLUMN {col} TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
|
||||
else:
|
||||
db.execute(f"ALTER TABLE todos ADD COLUMN {col} TEXT")
|
||||
print(f"{label}: checked, {len(missing)} missing columns added" if missing else f"{label}: schema OK")
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
ensure_todos(project_db, "project db")
|
||||
ensure_todos(real_db, "real db")
|
||||
print("\nDone. Both DBs now have matching todos schema.")
|
||||
Reference in New Issue
Block a user