db_session.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. """Formal PostgreSQL session helpers for the creation-knowledge state store."""
  2. from __future__ import annotations
  3. from contextlib import contextmanager
  4. from typing import Any, Iterator
  5. import psycopg2
  6. import psycopg2.extras
  7. from core.config import CreationDbConfig
  8. psycopg2.extras.register_uuid()
  9. def connect(config: CreationDbConfig) -> Any:
  10. """Open a PostgreSQL connection scoped to the formal state schema."""
  11. return psycopg2.connect(
  12. host=config.host,
  13. port=config.port,
  14. user=config.user,
  15. password=config.password,
  16. dbname=config.database,
  17. connect_timeout=config.timeout,
  18. application_name=config.application_name,
  19. options=f"-c search_path={config.schema},public",
  20. )
  21. @contextmanager
  22. def transaction(config: CreationDbConfig) -> Iterator[Any]:
  23. """Yield a connection and commit or roll back around the caller's work."""
  24. conn = connect(config)
  25. try:
  26. yield conn
  27. conn.commit()
  28. except Exception:
  29. conn.rollback()
  30. raise
  31. finally:
  32. conn.close()
  33. def fetch_all(
  34. config: CreationDbConfig,
  35. sql: str,
  36. params: tuple[Any, ...] = (),
  37. ) -> list[dict[str, Any]]:
  38. """Small read helper for diagnostics and repository smoke checks."""
  39. conn = connect(config)
  40. try:
  41. with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
  42. cur.execute(sql, params)
  43. return [dict(row) for row in cur.fetchall()]
  44. finally:
  45. conn.close()