одно DB-соединение на сборку чанков (вместо 7 отдельных), v1.18

This commit is contained in:
2026-06-17 17:37:27 +04:00
parent 0dac6bf37b
commit ba5933b715
2 changed files with 56 additions and 19 deletions
+55 -18
View File
@@ -18,8 +18,30 @@ from api import api_bp
load_dotenv()
def _save_file_to_db(filename, file_bytes, mime, contract_id):
"""Сохранить один файл в БД: documents + supplements. Возвращает doc_id или None."""
def _save_file_to_db(filename, file_bytes, mime, contract_id, conn=None):
"""Сохранить файл в БД. Если conn передан — использовать его, иначе свои подключения."""
if conn:
cur = conn.cursor()
cur.execute(
"INSERT INTO documents (filename, mime_type, original_bytes, status) VALUES (%s,%s,%s,'uploaded')",
(filename, mime, file_bytes),
)
cur.execute(
"SELECT id FROM documents WHERE filename=%s AND status='uploaded' ORDER BY created_at DESC LIMIT 1",
(filename,),
)
row = cur.fetchone()
doc_id = row[0] if row else None
if doc_id:
cur.execute(
"INSERT INTO supplements (contract_id, document_id, type) VALUES (%s,%s,'initial')",
(str(contract_id), str(doc_id)),
)
conn.commit()
cur.close()
return doc_id
# Без соединения — каждое действие со своим (старый режим)
db.execute(
"INSERT INTO documents (filename, mime_type, original_bytes, status) VALUES (%s,%s,%s,'uploaded')",
(filename, mime, file_bytes),
@@ -129,43 +151,58 @@ class ContractsApp:
if received == total_chunks:
try:
# ОДНО соединение на всю сборку + сохранение
conn, err = db.connect()
if err:
return jsonify({"error": f"БД: {err}"}), 500
cur = conn.cursor()
# Собрать все чанки по порядку
rows_res, _ = db.query(
cur.execute(
"SELECT chunk_data FROM chunks WHERE upload_id=%s ORDER BY chunk_index",
(upload_id,),
)
file_bytes = b"".join(r[0] for r in rows_res["rows"])
file_bytes = b"".join(r[0] for r in cur.fetchall())
# Получить метаданные из первой записи
meta, _ = db.query_one(
# Метаданные
cur.execute(
"SELECT filename, mime, cid FROM chunks WHERE upload_id=%s LIMIT 1",
(upload_id,),
)
fname = meta["filename"] if meta else filename
fmime = meta["mime"] if meta else mime
fcid = meta["cid"] if meta else cid
meta = cur.fetchone()
fname = meta[0] if meta else filename
fmime = meta[1] if meta else mime
fcid = meta[2] if meta else cid
# Создать контракт если нет
# Контракт если нет
if fcid:
contract_id = fcid
else:
conn, err = db.connect()
if err:
return jsonify({"error": f"БД: {err}"}), 500
cur = conn.cursor()
cur.execute(
"INSERT INTO contracts (number, client) VALUES (%s, %s) RETURNING id",
("б" + __import__("datetime").datetime.now().strftime("%Y%m%d-%H%M"), ""),
)
contract_id = cur.fetchone()[0]
conn.commit()
conn.commit()
# Сохранить файл через то же соединение
doc_id = _save_file_to_db(fname, file_bytes, fmime, str(contract_id), conn=conn)
if not doc_id:
conn.rollback()
cur.close()
conn.close()
doc_id = _save_file_to_db(fname, file_bytes, fmime, str(contract_id))
if not doc_id:
return jsonify({"error": "Не удалось сохранить файл в БД"}), 500
cur.close()
conn.close()
except Exception as e:
try: conn.rollback()
except: pass
try: cur.close()
except: pass
try: conn.close()
except: pass
return jsonify({"error": f"Сборка: {e}"}), 500
finally:
db.execute("DELETE FROM chunks WHERE upload_id=%s", (upload_id,))
+1 -1
View File
@@ -59,7 +59,7 @@
<body>
<div class="topbar">
<img src="{{ url_for('static', filename='nubes-logo.svg') }}" alt="Nubes">
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.17</span></span>
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.18</span></span>
</div>
<div class="content">