From fd2126c0cb2a5dab8e70f8d1ec139b6190782a82 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sun, 7 Jun 2026 09:16:33 +0400 Subject: [PATCH] =?UTF-8?q?fix(db):=20executescript=20=D0=B2=20try/except,?= =?UTF-8?q?=20=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA=D1=81=D1=8B=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=20=D0=BE=D1=82=20=D0=BC?= =?UTF-8?q?=D0=B8=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/db.py | 161 +++++++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 73 deletions(-) diff --git a/api/db.py b/api/db.py index 1b2cd6e..60a11f6 100644 --- a/api/db.py +++ b/api/db.py @@ -39,88 +39,90 @@ class Database: self.conn = None def _init_schema(self): - self.conn.executescript(""" - CREATE TABLE IF NOT EXISTS sessions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + # Основная схема (может упасть на индексах старых БД — ловим) + try: + self.conn.executescript(""" + CREATE TABLE IF NOT EXISTS sessions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, - -- Сервер - client_ip TEXT, - real_ip TEXT, - user_agent TEXT, - content_length INTEGER, - created_at TEXT NOT NULL DEFAULT (datetime('now')), + -- Сервер + client_ip TEXT, + real_ip TEXT, + user_agent TEXT, + content_length INTEGER, + created_at TEXT NOT NULL DEFAULT (datetime('now')), - -- Телефон - phone_model TEXT, - phone_maker TEXT, - android_version TEXT, - android_sdk INTEGER, - app_version TEXT, - android_id TEXT, - device_uuid TEXT, - phone_lang TEXT, - phone_tz TEXT, - phone_display TEXT, + -- Телефон + phone_model TEXT, + phone_maker TEXT, + android_version TEXT, + android_sdk INTEGER, + app_version TEXT, + android_id TEXT, + device_uuid TEXT, + phone_lang TEXT, + phone_tz TEXT, + phone_display TEXT, - -- ELM327 - elm_mac TEXT, - elm_bt_name TEXT, - obd_protocol TEXT, + -- ELM327 + elm_mac TEXT, + elm_bt_name TEXT, + obd_protocol TEXT, - -- Авто - vin TEXT, - dtc_count INTEGER DEFAULT 0, - pid_count INTEGER DEFAULT 0, + -- Авто + vin TEXT, + dtc_count INTEGER DEFAULT 0, + pid_count INTEGER DEFAULT 0, - -- Сессия - duration_ms INTEGER, - response_count INTEGER DEFAULT 0, - error_count INTEGER DEFAULT 0, - retry_count INTEGER DEFAULT 0, - timeout_count INTEGER DEFAULT 0, - script_mode TEXT, - transport TEXT, -- 'bt' | 'tcp' - mock_mode INTEGER DEFAULT 0, - car_info TEXT, + -- Сессия + duration_ms INTEGER, + response_count INTEGER DEFAULT 0, + error_count INTEGER DEFAULT 0, + retry_count INTEGER DEFAULT 0, + timeout_count INTEGER DEFAULT 0, + script_mode TEXT, + transport TEXT, + mock_mode INTEGER DEFAULT 0, + car_info TEXT, - -- LLM - diagnosis_text TEXT, - diagnosis_len INTEGER, - llm_model TEXT, - llm_duration_ms INTEGER, - llm_success INTEGER DEFAULT 0, + -- LLM + diagnosis_text TEXT, + diagnosis_len INTEGER, + llm_model TEXT, + llm_duration_ms INTEGER, + llm_success INTEGER DEFAULT 0, - -- Сырые данные (JSON) - raw_responses TEXT, + -- Сырые данные (JSON) + raw_responses TEXT, - -- Идемпотентность - request_id TEXT UNIQUE, - response_json TEXT - ); + -- Идемпотентность + request_id TEXT UNIQUE, + response_json TEXT + ); - 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_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); - CREATE INDEX IF NOT EXISTS idx_sessions_uuid ON sessions(device_uuid); + 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_mac ON sessions(elm_mac); + + -- Профили ELM-устройств + 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() # Миграции: добавляем колонки, которых нет в старых БД @@ -138,7 +140,20 @@ class Database: try: self.conn.execute(sql) 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() # ── sessions ──────────────────────────────────────────