chore(api): stabilize SQL core and enhance searchability

- Refactor SQL CRUD to use engine.connect() context managers for thread safety
- Optimize connection pooling in lib_sql_core
- Clean up app/routers/api.py to fix duplicate definitions and OpenAPI KeyError
- Add 'default_qry_str' to searchable_fields for Event, Session, Presentation, Presenter, Badge, and Journal
- Add 'event_location_name' to searchable_fields for Event Session
- Verified 20/20 E2E success via repro_intermittent_errors.py
This commit is contained in:
Scott Idem
2026-01-21 15:23:04 -05:00
parent 89bf87cb62
commit 6ca79e9a02
9 changed files with 263 additions and 833 deletions

View File

@@ -9,6 +9,7 @@ from sqlalchemy import create_engine
from app.config import settings
log = logging.getLogger('root')
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
# 1. Thread-local storage for capturing last SQL error message
_sql_error_state = threading.local()
@@ -27,29 +28,32 @@ def set_last_sql_error(error: Any):
# 2. Initial Engine Setup
db_uri = settings.SQLALCHEMY_DB_URI
engine = create_engine(
url = db_uri,
echo = False,
pool_use_lifo = True,
pool_pre_ping = True,
pool_recycle = settings.DB['pool_recycle'],
isolation_level = 'READ COMMITTED',
connect_args = {'connect_timeout': settings.DB['connect_timeout']}
)
def create_ae_engine(uri: str):
return create_engine(
url = uri,
echo = False,
pool_size = settings.DB.get('pool_size', 10),
max_overflow = settings.DB.get('max_overflow', 20),
pool_use_lifo = True,
pool_pre_ping = True,
pool_recycle = settings.DB['pool_recycle'],
isolation_level = 'READ COMMITTED',
connect_args = {'connect_timeout': settings.DB['connect_timeout']}
)
log.info('DB SQL Core: Initializing connection...')
db = None
try:
db = engine.connect()
log.info(f'DB SQL Core: Connected to database: {db_uri}')
except Exception:
log.exception('DB SQL Core: Could not connect to database.')
engine = create_ae_engine(db_uri)
# DEPRECATED: Global shared 'db' connection. Use engine.connect() in context managers instead.
# Keeping for legacy compatibility but will phase out usage in crud lib.
db = engine.connect()
log.info('DB SQL Core: Initializing engine...')
# 3. Connection Management Logic
def reconnect_db() -> bool:
"""
Re-initializes the global database engine and connection using current settings.
Re-initializes the global database engine using current settings.
Useful after bootstrapping new credentials from the 'cfg' table.
"""
global engine, db, db_uri
@@ -61,28 +65,16 @@ def reconnect_db() -> bool:
log.info("DB SQL Core: Disposed of previous database engine.")
db_uri = settings.SQLALCHEMY_DB_URI
engine = create_engine(
url = db_uri,
echo = False,
pool_use_lifo = True,
pool_pre_ping = True,
pool_recycle = settings.DB['pool_recycle'],
isolation_level = 'READ COMMITTED',
connect_args = {'connect_timeout': settings.DB['connect_timeout']}
)
engine = create_ae_engine(db_uri)
db = engine.connect()
log.info(f"DB SQL Core: Database connection re-established successfully: {db_uri}")
log.info(f"DB SQL Core: Database engine re-established successfully: {db_uri}")
return True
except Exception:
log.exception("DB SQL Core: FAILED to refresh database connection!")
log.exception("DB SQL Core: FAILED to refresh database engine!")
return False
def sql_connect(current_db=None, log_lvl: int = logging.INFO) -> bool:
"""Refreshes the global database connection."""
log.setLevel(log_lvl)
log.info('DB SQL Core: Refreshing database connection via sql_connect...')
return reconnect_db()