""" app.py — Flask CRUD-интерфейс для PostgreSQL. Переменные окружения (из json_env): - PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD — подключение к БД - TABLE_NAME — имя таблицы (по умолчанию crud_items) При старте: CREATE TABLE IF NOT EXISTS (БЕЗ DROP). """ import os import psycopg2 import psycopg2.extras from flask import Flask, render_template, request, redirect, url_for, g VERSION = "1.0.0" TABLE_NAME = os.environ.get("TABLE_NAME", "crud_items") app = Flask(__name__) def get_db(): """Ленивое подключение к PostgreSQL. Один коннект на запрос.""" if "db" not in g: g.db = psycopg2.connect( host=os.environ.get("PGHOST", "127.0.0.1"), port=os.environ.get("PGPORT", "5432"), dbname=os.environ.get("PGDATABASE", "postgres"), user=os.environ.get("PGUSER", "postgres"), password=os.environ.get("PGPASSWORD", ""), ) g.db.autocommit = True return g.db def init_db(): """CREATE TABLE IF NOT EXISTS — никогда не дропает существующую таблицу.""" db = get_db() cur = db.cursor() cur.execute( f""" CREATE TABLE IF NOT EXISTS {TABLE_NAME} ( id SERIAL PRIMARY KEY, value TEXT NOT NULL DEFAULT '' ) """ ) cur.close() @app.teardown_appcontext def close_db(exc): db = g.pop("db", None) if db is not None: db.close() @app.route("/", methods=["GET", "POST"]) def index(): db = get_db() cur = db.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # --- Обработка POST (create / update / delete) — POST-redirect-GET --- if request.method == "POST": action = request.form.get("action", "") if action == "create": cur.execute( f"INSERT INTO {TABLE_NAME} (value) VALUES (%s)", (request.form.get("value", ""),), ) elif action == "update": cur.execute( f"UPDATE {TABLE_NAME} SET value = %s WHERE id = %s", (request.form.get("value", ""), int(request.form.get("id", 0))), ) elif action == "delete": cur.execute( f"DELETE FROM {TABLE_NAME} WHERE id = %s", (int(request.form.get("id", 0)),), ) cur.close() return redirect(url_for("index")) # --- GET: список + форма редактирования --- edit_row = None edit_id = request.args.get("edit") if edit_id: cur.execute( f"SELECT id, value FROM {TABLE_NAME} WHERE id = %s", (int(edit_id),), ) row = cur.fetchone() if row: edit_row = dict(row) # Список всех записей cur.execute(f"SELECT id, value FROM {TABLE_NAME} ORDER BY id") rows = cur.fetchall() cur.close() return render_template( "index.html", table_name=TABLE_NAME, rows=rows, edit_row=edit_row, version=VERSION, ) # --- Инициализация БД при старте (до первого запроса) --- with app.app_context(): init_db() if __name__ == "__main__": app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)), debug=False)