81 lines
2.1 KiB
Python
81 lines
2.1 KiB
Python
import psycopg2
|
||
import psycopg2.extras
|
||
import psycopg2.pool
|
||
from flask import g, current_app
|
||
|
||
# Module-level connection pool (initialised once per process)
|
||
_pool = None
|
||
|
||
|
||
def init_db(app):
|
||
"""Initialise the connection pool on startup."""
|
||
global _pool
|
||
try:
|
||
_pool = psycopg2.pool.SimpleConnectionPool(
|
||
minconn=2,
|
||
maxconn=10,
|
||
dsn=app.config["DATABASE_URL"],
|
||
)
|
||
print(" * Database connection pool OK (2–10 connections)")
|
||
except Exception as e:
|
||
print(f" * Database connection pool FAILED: {e}")
|
||
|
||
|
||
def get_db():
|
||
"""Get a pooled database connection for the current request."""
|
||
if "db" not in g:
|
||
g.db = _pool.getconn()
|
||
g.db.cursor_factory = psycopg2.extras.RealDictCursor
|
||
return g.db
|
||
|
||
|
||
def close_db(exception=None):
|
||
"""Return database connection to the pool at end of request."""
|
||
db = g.pop("db", None)
|
||
if db is not None:
|
||
if exception:
|
||
db.rollback()
|
||
_pool.putconn(db)
|
||
|
||
|
||
def query(sql, params=None):
|
||
"""Execute a SELECT query and return all rows as dicts."""
|
||
db = get_db()
|
||
with db.cursor() as cur:
|
||
cur.execute(sql, params)
|
||
return cur.fetchall()
|
||
|
||
|
||
def query_one(sql, params=None):
|
||
"""Execute a SELECT query and return one row as a dict."""
|
||
db = get_db()
|
||
with db.cursor() as cur:
|
||
cur.execute(sql, params)
|
||
return cur.fetchone()
|
||
|
||
|
||
def execute(sql, params=None):
|
||
"""Execute an INSERT/UPDATE/DELETE and commit."""
|
||
db = get_db()
|
||
with db.cursor() as cur:
|
||
cur.execute(sql, params)
|
||
db.commit()
|
||
|
||
|
||
def execute_returning(sql, params=None):
|
||
"""Execute an INSERT/UPDATE/DELETE with RETURNING and commit."""
|
||
db = get_db()
|
||
with db.cursor() as cur:
|
||
cur.execute(sql, params)
|
||
row = cur.fetchone()
|
||
db.commit()
|
||
return row
|
||
|
||
|
||
def execute_many(sql, params_list):
|
||
"""Execute a batch INSERT/UPDATE/DELETE and commit."""
|
||
db = get_db()
|
||
with db.cursor() as cur:
|
||
cur.executemany(sql, params_list)
|
||
db.commit()
|