одно 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() load_dotenv()
def _save_file_to_db(filename, file_bytes, mime, contract_id): def _save_file_to_db(filename, file_bytes, mime, contract_id, conn=None):
"""Сохранить один файл в БД: documents + supplements. Возвращает doc_id или 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( db.execute(
"INSERT INTO documents (filename, mime_type, original_bytes, status) VALUES (%s,%s,%s,'uploaded')", "INSERT INTO documents (filename, mime_type, original_bytes, status) VALUES (%s,%s,%s,'uploaded')",
(filename, mime, file_bytes), (filename, mime, file_bytes),
@@ -129,43 +151,58 @@ class ContractsApp:
if received == total_chunks: if received == total_chunks:
try: 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", "SELECT chunk_data FROM chunks WHERE upload_id=%s ORDER BY chunk_index",
(upload_id,), (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", "SELECT filename, mime, cid FROM chunks WHERE upload_id=%s LIMIT 1",
(upload_id,), (upload_id,),
) )
fname = meta["filename"] if meta else filename meta = cur.fetchone()
fmime = meta["mime"] if meta else mime fname = meta[0] if meta else filename
fcid = meta["cid"] if meta else cid fmime = meta[1] if meta else mime
fcid = meta[2] if meta else cid
# Создать контракт если нет # Контракт если нет
if fcid: if fcid:
contract_id = fcid contract_id = fcid
else: else:
conn, err = db.connect()
if err:
return jsonify({"error": f"БД: {err}"}), 500
cur = conn.cursor()
cur.execute( cur.execute(
"INSERT INTO contracts (number, client) VALUES (%s, %s) RETURNING id", "INSERT INTO contracts (number, client) VALUES (%s, %s) RETURNING id",
("б" + __import__("datetime").datetime.now().strftime("%Y%m%d-%H%M"), ""), ("б" + __import__("datetime").datetime.now().strftime("%Y%m%d-%H%M"), ""),
) )
contract_id = cur.fetchone()[0] 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() cur.close()
conn.close() conn.close()
doc_id = _save_file_to_db(fname, file_bytes, fmime, str(contract_id))
if not doc_id:
return jsonify({"error": "Не удалось сохранить файл в БД"}), 500 return jsonify({"error": "Не удалось сохранить файл в БД"}), 500
cur.close()
conn.close()
except Exception as e: 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 return jsonify({"error": f"Сборка: {e}"}), 500
finally: finally:
db.execute("DELETE FROM chunks WHERE upload_id=%s", (upload_id,)) db.execute("DELETE FROM chunks WHERE upload_id=%s", (upload_id,))
+1 -1
View File
@@ -59,7 +59,7 @@
<body> <body>
<div class="topbar"> <div class="topbar">
<img src="{{ url_for('static', filename='nubes-logo.svg') }}" alt="Nubes"> <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>
<div class="content"> <div class="content">