63 lines
3.2 KiB
Markdown
63 lines
3.2 KiB
Markdown
# Вопрос для Sonnet (без ссылок на файлы)
|
||
|
||
## Контекст
|
||
|
||
Мигрировали сервис "Сверка Договоров" с ВМ на Flask (managed Python, Штурвал).
|
||
Код готов — 22 эндпоинта, вся логика внутри Flask:
|
||
- upload (XHR + progress), unzip, convert-doc
|
||
- классификация (LLM, ThreadPoolExecutor внутри Flask-потока для >10 файлов)
|
||
- группировка
|
||
- сравнение через SSE с heartbeat
|
||
- CRUD документов, supplements, промптов
|
||
- чат с LLM по результатам спецификации
|
||
|
||
Архитектура: db/ (чистый CRUD) → services/ (бизнес-логика) → routes/ (Flask blueprints).
|
||
|
||
## Проблема
|
||
|
||
Сейчас БД — PostgreSQL. Но данные ВРЕМЕННЫЕ:
|
||
- При загрузке страницы cleanup() → DELETE ALL из всех таблиц (кроме prompts)
|
||
- Юзер загрузил файлы → обработал → закрыл → данные не нужны
|
||
- Файлы хранятся как base64 в БД (конфиденциально, должны умереть с сессией)
|
||
|
||
Поднимать отдельный PostgreSQL-сервис в кластере ради временных данных — overkill.
|
||
|
||
## Предложение
|
||
|
||
Заменить PostgreSQL на SQLite (stdlib sqlite3):
|
||
- База — файл /tmp/contracts.db внутри Flask-контейнера
|
||
- connection.py переписать (~80 строк), db/*.py — мелкие правки (~30 строк)
|
||
- Остальной код (services, routes) — без изменений
|
||
- cleanup → os.remove() — атомарно, никаких DELETE, данные гарантированно исчезли
|
||
- Упал контейнер → файл исчез
|
||
|
||
## Детальнее про конкурентность
|
||
|
||
В НАШЕЙ архитектуре:
|
||
1. Classify запускается ВНУТРИ Flask-процесса как daemon-поток (threading.Thread), НЕ отдельный процесс
|
||
2. ThreadPoolExecutor(max_workers=4) внутри classify — 4 потока шлют запросы к LLM API
|
||
3. SSE-стриминг — читает БД, один writer (classify), один reader (SSE)
|
||
4. Обычно classify синхронный (≤10 файлов) — вообще один поток
|
||
|
||
То есть: ОДИН процесс Flask, несколько потоков. Несколько процессов нет.
|
||
|
||
## Что меняется в коде
|
||
|
||
connection.py:
|
||
- psycopg2.pool → sqlite3 с thread-local соединениями
|
||
- threading.local() + get_conn() на каждый поток
|
||
- PRAGMA journal_mode=WAL
|
||
- check_same_thread=False
|
||
|
||
db/*.py:
|
||
- %s → ? (sqlite-стиль placeholders)
|
||
- RETURNING * → lastrowid + отдельный SELECT
|
||
- ::jsonb → json.dumps()
|
||
- BOOLEAN → INTEGER (0/1)
|
||
|
||
Остальное без изменений.
|
||
|
||
## Вопрос
|
||
|
||
Есть ли подводные камни с SQLite для этой конкретной архитектуры (один процесс, несколько потоков, WAL, thread-local connections)?
|