Public Access
fix: close DB session in run_step finally block
Wraps the SessionLocal body in try/finally so db.close() is always called, preventing connection leaks on exception. Updates the test monkeypatch to use a no-op close() proxy so the transactional fixture stays live after run_step returns. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,18 +63,21 @@ def run_step(step_name: str, week_start_date: Optional[date] = None) -> None:
|
|||||||
|
|
||||||
week = week_start_date or _current_week_start()
|
week = week_start_date or _current_week_start()
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
families = db.query(FamilyProfile).all()
|
try:
|
||||||
if not families:
|
families = db.query(FamilyProfile).all()
|
||||||
logger.warning("run_step(%s): no family profiles, skipping", step_name)
|
if not families:
|
||||||
return
|
logger.warning("run_step(%s): no family profiles, skipping", step_name)
|
||||||
for family in families:
|
return
|
||||||
run = _get_or_create_run(db, family.id, week)
|
for family in families:
|
||||||
try:
|
run = _get_or_create_run(db, family.id, week)
|
||||||
step_fns[step_name](run, db)
|
try:
|
||||||
except Exception:
|
step_fns[step_name](run, db)
|
||||||
logger.exception(
|
except Exception:
|
||||||
"run_step(%s) failed for family %s", step_name, family.id
|
logger.exception(
|
||||||
)
|
"run_step(%s) failed for family %s", step_name, family.id
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
def run_week(week_start_date: Optional[date] = None) -> None:
|
def run_week(week_start_date: Optional[date] = None) -> None:
|
||||||
|
|||||||
@@ -434,9 +434,18 @@ def test_run_step_upserts_weekly_run(db, family, monkeypatch):
|
|||||||
"app.services.orchestrator.steps.ScraperService.run_scrape",
|
"app.services.orchestrator.steps.ScraperService.run_scrape",
|
||||||
lambda self, **kw: {"status": "success", "items_scraped": 0},
|
lambda self, **kw: {"status": "success", "items_scraped": 0},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class _NoCloseSession:
|
||||||
|
"""Proxy that delegates all attribute access to the test session
|
||||||
|
but turns close() into a no-op so the transactional fixture stays live."""
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(db, name)
|
||||||
|
def close(self):
|
||||||
|
pass
|
||||||
|
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"app.services.orchestrator.runner.SessionLocal",
|
"app.services.orchestrator.runner.SessionLocal",
|
||||||
lambda: db,
|
lambda: _NoCloseSession(),
|
||||||
)
|
)
|
||||||
from app.services.orchestrator.runner import run_step
|
from app.services.orchestrator.runner import run_step
|
||||||
run_step("scrape", WEEK)
|
run_step("scrape", WEEK)
|
||||||
|
|||||||
Reference in New Issue
Block a user