Files
ai-balance-monitor/app/db.py
T

84 lines
2.9 KiB
Python

"""SQLite 数据层:连接短生命周期(每次操作新建),线程安全。"""
from __future__ import annotations
import sqlite3
from pathlib import Path
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
DB_PATH = DATA_DIR / "monitor.db"
SCHEMA = """
CREATE TABLE IF NOT EXISTS platforms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
currency TEXT NOT NULL DEFAULT 'USD',
icon TEXT NOT NULL DEFAULT '',
method TEXT NOT NULL DEFAULT 'GET',
url TEXT NOT NULL,
headers TEXT NOT NULL DEFAULT '{}',
body TEXT NOT NULL DEFAULT '',
balance_path TEXT NOT NULL,
interval_seconds INTEGER,
retry_count INTEGER,
timeout_seconds INTEGER,
enabled INTEGER NOT NULL DEFAULT 1,
note TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
CREATE TABLE IF NOT EXISTS accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform_id INTEGER NOT NULL REFERENCES platforms(id) ON DELETE CASCADE,
name TEXT NOT NULL,
api_key TEXT NOT NULL,
threshold REAL NOT NULL DEFAULT 0,
enabled INTEGER NOT NULL DEFAULT 1,
alert_armed INTEGER NOT NULL DEFAULT 1,
last_balance REAL,
last_status TEXT NOT NULL DEFAULT 'pending',
last_error TEXT NOT NULL DEFAULT '',
last_check_at TEXT,
note TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
CREATE TABLE IF NOT EXISTS balance_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
balance REAL NOT NULL,
checked_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
CREATE TABLE IF NOT EXISTS alert_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL,
type TEXT NOT NULL,
message TEXT NOT NULL,
sent_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
CREATE INDEX IF NOT EXISTS idx_accounts_platform ON accounts(platform_id);
CREATE INDEX IF NOT EXISTS idx_history_account ON balance_history(account_id, id);
CREATE INDEX IF NOT EXISTS idx_alert_account ON alert_log(account_id);
"""
def get_conn() -> sqlite3.Connection:
conn = sqlite3.connect(DB_PATH, timeout=30)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA foreign_keys = ON")
return conn
def init_db() -> None:
DATA_DIR.mkdir(parents=True, exist_ok=True)
with get_conn() as conn:
conn.executescript(SCHEMA)
def rows_to_dicts(rows: list[sqlite3.Row]) -> list[dict]:
return [dict(r) for r in rows]