feat: schema.py (DDL 5 таблиц), db.py без DDL, app.py минимальный, test_routes с комментариями

По рекомендации Sonnet:
- schema.py — все DDL (documents, contracts, supplements, spec_rows, spec_history)
- db.py — только транспорт (connect/query), DDL убран
- app.py — минимальный: ensure_schema() + register_blueprint()
- test_routes.py — подробные комментарии, исправлен импорт psysql
This commit is contained in:
2026-06-13 17:14:48 +04:00
parent 308be45ce8
commit cbfba0bc54
5 changed files with 260 additions and 38 deletions
+28 -25
View File
@@ -1,10 +1,26 @@
"""
db.py — Транспортный слой к базе данных.
Только connect() и query(). Никакой бизнес-логики, никакого DDL.
DDL → schema.py. Бизнес-запросы → upload.py, extractor.py, api.py.
Функции:
_pg_connect(dbname) — сырое подключение к ЛЮБОЙ базе (используется /test createdb)
connect() — подключение к ЦЕЛЕВОЙ базе (из DB_NAME)
query(sql, params) — выполнить запрос → (result, error)
"""
import os
import psycopg2
from psycopg2 import sql
def _pg_connect(dbname):
"""Сырое подключение к указанной базе."""
"""
Сырое подключение к указанной базе данных.
Используется:
- connect() для целевой БД
- test_routes.py для /test createdb (подключение к 'postgres')
"""
return psycopg2.connect(
host=os.getenv("DB_HOST"),
port=os.getenv("DB_PORT", 5432),
@@ -16,36 +32,23 @@ def _pg_connect(dbname):
def connect():
"""Подключение к целевой БД. Возвращает (connection, None) или (None, error)."""
"""
Подключение к ЦЕЛЕВОЙ базе данных (DB_NAME из переменных окружения).
Возвращает (connection, None) при успехе или (None, error) при ошибке.
"""
try:
return _pg_connect(os.getenv("DB_NAME")), None
except Exception as e:
return None, str(e)
def ensure_db():
"""Создать базу, если не существует."""
db_name = os.getenv("DB_NAME", "contracts")
try:
conn = _pg_connect("postgres")
conn.autocommit = True
cur = conn.cursor()
cur.execute("SELECT 1 FROM pg_database WHERE datname = %s", (db_name,))
if cur.fetchone():
print(f"DB '{db_name}' exists")
else:
cur.execute(sql.SQL("CREATE DATABASE {}").format(sql.Identifier(db_name)))
print(f"DB '{db_name}' created")
cur.close()
conn.close()
return True
except Exception as e:
print(f"ensure_db error: {e}")
return False
def query(sql_text, params=None):
"""Выполнить запрос, вернуть (result, error)."""
"""
Выполнить SQL-запрос к целевой БД.
Возвращает (result, None) или (None, error).
result = {"columns": [...], "rows": [[...], ...]}
"""
conn, err = connect()
if err:
return None, f"connect: {err}"