feat: слои db.py + test_routes (Blueprint /test)

This commit is contained in:
2026-06-13 12:02:46 +04:00
parent 684b4cc9c0
commit dbbc8ea5fe
4 changed files with 89 additions and 18 deletions
View File
+5 -18
View File
@@ -1,37 +1,24 @@
import os import os
import psycopg2
from dotenv import load_dotenv from dotenv import load_dotenv
from flask import Flask, render_template from flask import Flask, render_template
from . import db
from .test_routes import test_bp
load_dotenv() load_dotenv()
class ContractsApp: class ContractsApp:
def __init__(self): def __init__(self):
self.app = Flask(__name__) self.app = Flask(__name__)
self.db = self._connect_db()
self.add_routes() self.add_routes()
def _connect_db(self):
try:
conn = psycopg2.connect(
host=os.getenv("DB_HOST"),
port=os.getenv("DB_PORT", 5432),
dbname=os.getenv("DB_NAME"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASS"),
sslmode=os.getenv("DB_SSLMODE", "disable"),
)
return conn
except Exception as e:
print(f"DB connect error: {e}")
return None
def add_routes(self): def add_routes(self):
self.app.add_url_rule("/", "index", self.index) self.app.add_url_rule("/", "index", self.index)
self.app.add_url_rule("/health", "health", self.health) self.app.add_url_rule("/health", "health", self.health)
self.app.register_blueprint(test_bp)
def index(self): def index(self):
db_status = "connected" if self.db else "no DB" conn = db.connect()
db_status = "connected" if conn else "no DB"
return render_template("index.html", db_status=db_status) return render_template("index.html", db_status=db_status)
def health(self): def health(self):
+36
View File
@@ -0,0 +1,36 @@
import os
import psycopg2
from psycopg2 import sql
def connect():
"""Подключение к БД. Возвращает connection или None."""
try:
return psycopg2.connect(
host=os.getenv("DB_HOST"),
port=os.getenv("DB_PORT", 5432),
dbname=os.getenv("DB_NAME"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASS"),
sslmode=os.getenv("DB_SSLMODE", "disable"),
)
except Exception:
return None
def query(sql_text, params=None):
"""Выполнить запрос, вернуть (rows, columns) или (None, error)."""
conn = connect()
if not conn:
return None, "no connection"
try:
cur = conn.cursor()
cur.execute(sql_text, params)
rows = cur.fetchall()
cols = [desc[0] for desc in cur.description] if cur.description else []
cur.close()
conn.close()
return {"columns": cols, "rows": [list(r) for r in rows]}, None
except Exception as e:
conn.close()
return None, str(e)
+48
View File
@@ -0,0 +1,48 @@
from flask import Blueprint, jsonify, request
from . import db
test_bp = Blueprint("test", __name__)
@test_bp.route("/test", methods=["GET", "POST"])
def test():
"""Тестовый слой: проверка БД и выполнение запросов."""
# GET — статус
if request.method == "GET":
conn = db.connect()
return jsonify({
"db": "ok" if conn else "fail",
"actions": [
"GET /test — статус БД",
"POST /test SQL:... — выполнить запрос",
"POST /test tables — список таблиц",
],
})
# POST — выполнить действие
data = request.get_json(silent=True) or {}
action = data.get("action", "status")
if action == "status":
conn = db.connect()
return jsonify({"db": "ok" if conn else "fail"})
if action == "tables":
result, err = db.query(
"SELECT table_name FROM information_schema.tables WHERE table_schema='public' ORDER BY table_name"
)
if err:
return jsonify({"error": err}), 500
return jsonify({"tables": [r[0] for r in result["rows"]]})
if action == "sql":
sql_text = data.get("sql", "")
if not sql_text:
return jsonify({"error": "no sql"}), 400
result, err = db.query(sql_text)
if err:
return jsonify({"error": err}), 500
return jsonify(result)
return jsonify({"error": f"unknown action: {action}"}), 400