File size: 730 Bytes
4fd1234 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import os
import psycopg2
from psycopg2.extras import RealDictCursor
from contextlib import contextmanager
import logging
logger = logging.getLogger(__name__)
@contextmanager
def get_cursor():
"""
New connection per call — psycopg2 is not thread-safe across Gradio workers.
Commits on clean exit, rolls back on exception.
"""
url = os.environ.get("DATABASE_URL")
if not url:
raise RuntimeError("DATABASE_URL not set — is Docker Compose running?")
conn = psycopg2.connect(url)
try:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
yield cur
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
|