feat: слои db.py + test_routes (Blueprint /test)
This commit is contained in:
+5
-18
@@ -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
@@ -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)
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user