feat: зеркало кода ВМ — deploy/ из contractor

This commit is contained in:
2026-06-27 19:35:53 +04:00
parent de074c8f99
commit 623cd9140f
30 changed files with 4805 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
"""
Database connection — psycopg2 connection pool.
Архитектурное решение (Opus):
- ThreadedConnectionPool(minconn=1, maxconn=10) — оптимально для ThreadingMixIn HTTP-сервера.
Каждый HTTP-запрос в отдельном потоке получает своё соединение из пула.
- RealDictCursor для query() — возвращает dict с lowercase ключами (консистентно с Python API).
- execute()/execute_returning() — для INSERT/UPDATE/DELETE с автокоммитом и откатом при ошибке.
- Пул создаётся лениво (при первом запросе) через get_pool().
"""
import os
import psycopg2
import psycopg2.pool
import psycopg2.extras
# Глобальный пул соединений (singleton)
_pool = None
# Параметры подключения из переменных окружения (systemd Environment)
DB_CONFIG = {
"host": os.getenv("DB_HOST", "127.0.0.1"),
"port": int(os.getenv("DB_PORT", "5432")),
"dbname": os.getenv("DB_NAME", "baza"),
"user": os.getenv("DB_USER", "super"),
"password": os.getenv("DB_PASS", ""),
}
def get_pool():
"""Возвращает глобальный пул соединений. Создаёт при первом вызове."""
global _pool
if _pool is None:
_pool = psycopg2.pool.ThreadedConnectionPool(
minconn=1, maxconn=10, **DB_CONFIG
)
return _pool
def query(sql, params=None):
"""
SELECT → list[dict] с lowercase ключами.
Используется всеми db/*.py модулями для чтения данных.
"""
pool = get_pool()
conn = pool.getconn()
try:
with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
cur.execute(sql, params)
rows = cur.fetchall()
return [{k.lower(): v for k, v in r.items()} for r in rows]
finally:
pool.putconn(conn)
def execute(sql, params=None):
"""
INSERT/UPDATE/DELETE → количество затронутых строк.
Автокоммит. При ошибке — rollback и проброс исключения.
"""
pool = get_pool()
conn = pool.getconn()
try:
with conn.cursor() as cur:
cur.execute(sql, params)
conn.commit()
return cur.rowcount
except Exception:
conn.rollback()
raise
finally:
pool.putconn(conn)
def execute_returning(sql, params=None):
"""
INSERT/UPDATE/DELETE с RETURNING → dict первой строки.
Используется для insert с автогенерацией UUID (gen_random_uuid()).
"""
pool = get_pool()
conn = pool.getconn()
try:
with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
cur.execute(sql, params)
conn.commit()
row = cur.fetchone()
return {k.lower(): v for k, v in row.items()} if row else None
except Exception:
conn.rollback()
raise
finally:
pool.putconn(conn)