fix(db): executescript в try/except, индексы отдельно от миграций

This commit is contained in:
Repinoid
2026-06-07 09:16:33 +04:00
parent d5e44060d3
commit fd2126c0cb
+88 -73
View File
@@ -39,88 +39,90 @@ class Database:
self.conn = None self.conn = None
def _init_schema(self): def _init_schema(self):
self.conn.executescript(""" # Основная схема (может упасть на индексах старых БД — ловим)
CREATE TABLE IF NOT EXISTS sessions ( try:
id INTEGER PRIMARY KEY AUTOINCREMENT, self.conn.executescript("""
CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- Сервер -- Сервер
client_ip TEXT, client_ip TEXT,
real_ip TEXT, real_ip TEXT,
user_agent TEXT, user_agent TEXT,
content_length INTEGER, content_length INTEGER,
created_at TEXT NOT NULL DEFAULT (datetime('now')), created_at TEXT NOT NULL DEFAULT (datetime('now')),
-- Телефон -- Телефон
phone_model TEXT, phone_model TEXT,
phone_maker TEXT, phone_maker TEXT,
android_version TEXT, android_version TEXT,
android_sdk INTEGER, android_sdk INTEGER,
app_version TEXT, app_version TEXT,
android_id TEXT, android_id TEXT,
device_uuid TEXT, device_uuid TEXT,
phone_lang TEXT, phone_lang TEXT,
phone_tz TEXT, phone_tz TEXT,
phone_display TEXT, phone_display TEXT,
-- ELM327 -- ELM327
elm_mac TEXT, elm_mac TEXT,
elm_bt_name TEXT, elm_bt_name TEXT,
obd_protocol TEXT, obd_protocol TEXT,
-- Авто -- Авто
vin TEXT, vin TEXT,
dtc_count INTEGER DEFAULT 0, dtc_count INTEGER DEFAULT 0,
pid_count INTEGER DEFAULT 0, pid_count INTEGER DEFAULT 0,
-- Сессия -- Сессия
duration_ms INTEGER, duration_ms INTEGER,
response_count INTEGER DEFAULT 0, response_count INTEGER DEFAULT 0,
error_count INTEGER DEFAULT 0, error_count INTEGER DEFAULT 0,
retry_count INTEGER DEFAULT 0, retry_count INTEGER DEFAULT 0,
timeout_count INTEGER DEFAULT 0, timeout_count INTEGER DEFAULT 0,
script_mode TEXT, script_mode TEXT,
transport TEXT, -- 'bt' | 'tcp' transport TEXT,
mock_mode INTEGER DEFAULT 0, mock_mode INTEGER DEFAULT 0,
car_info TEXT, car_info TEXT,
-- LLM -- LLM
diagnosis_text TEXT, diagnosis_text TEXT,
diagnosis_len INTEGER, diagnosis_len INTEGER,
llm_model TEXT, llm_model TEXT,
llm_duration_ms INTEGER, llm_duration_ms INTEGER,
llm_success INTEGER DEFAULT 0, llm_success INTEGER DEFAULT 0,
-- Сырые данные (JSON) -- Сырые данные (JSON)
raw_responses TEXT, raw_responses TEXT,
-- Идемпотентность -- Идемпотентность
request_id TEXT UNIQUE, request_id TEXT UNIQUE,
response_json TEXT response_json TEXT
); );
CREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at); CREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at);
CREATE INDEX IF NOT EXISTS idx_sessions_vin ON sessions(vin); CREATE INDEX IF NOT EXISTS idx_sessions_vin ON sessions(vin);
CREATE INDEX IF NOT EXISTS idx_sessions_mac ON sessions(elm_mac); CREATE INDEX IF NOT EXISTS idx_sessions_mac ON sessions(elm_mac);
CREATE INDEX IF NOT EXISTS idx_sessions_aid ON sessions(android_id);
CREATE INDEX IF NOT EXISTS idx_sessions_request_id ON sessions(request_id); -- Профили ELM-устройств
CREATE INDEX IF NOT EXISTS idx_sessions_uuid ON sessions(device_uuid); CREATE TABLE IF NOT EXISTS device_profiles (
mac TEXT PRIMARY KEY,
level INTEGER NOT NULL,
elm_version TEXT,
elm_desc TEXT,
protocol TEXT,
voltage TEXT,
supported TEXT,
unsupported TEXT,
errors TEXT,
first_seen TEXT NOT NULL DEFAULT (datetime('now')),
last_seen TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_profiles_level ON device_profiles(level);
""")
except sqlite3.OperationalError:
pass # старая БД без новых колонок — применим миграции ниже
-- Профили ELM-устройств (по BT MAC)
CREATE TABLE IF NOT EXISTS device_profiles (
mac TEXT PRIMARY KEY, -- BT MAC-адрес
level INTEGER NOT NULL, -- 0/1/2 (-1 = нерабочее)
elm_version TEXT, -- ATI ответ
elm_desc TEXT, -- AT@1 (если есть)
protocol TEXT, -- ATDPN
voltage TEXT, -- ATRV
supported TEXT, -- JSON: ["ATE0","ATL0",...]
unsupported TEXT, -- JSON: ["ATAT1",...]
errors TEXT, -- JSON: ["ATCFC1: no response",...]
first_seen TEXT NOT NULL DEFAULT (datetime('now')),
last_seen TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_profiles_level ON device_profiles(level);
""")
self.conn.commit() self.conn.commit()
# Миграции: добавляем колонки, которых нет в старых БД # Миграции: добавляем колонки, которых нет в старых БД
@@ -138,7 +140,20 @@ class Database:
try: try:
self.conn.execute(sql) self.conn.execute(sql)
except sqlite3.OperationalError: except sqlite3.OperationalError:
pass # колонка уже существует pass
# Индексы для новых колонок (могут отсутствовать в старых БД)
index_migrations = [
"CREATE INDEX IF NOT EXISTS idx_sessions_aid ON sessions(android_id)",
"CREATE INDEX IF NOT EXISTS idx_sessions_uuid ON sessions(device_uuid)",
"CREATE INDEX IF NOT EXISTS idx_sessions_request_id ON sessions(request_id)",
]
for sql in index_migrations:
try:
self.conn.execute(sql)
except sqlite3.OperationalError:
pass
self.conn.commit() self.conn.commit()
# ── sessions ────────────────────────────────────────── # ── sessions ──────────────────────────────────────────