From 9326a82b294d22b8d6a2c9ad6a0cd4152a86ab51 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 29 Jun 2026 00:42:33 -0400 Subject: [PATCH] fix(heads): .all() before dict() in snapshot_head_metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dict(session.execute(...)) on a bare Result invokes the mapping protocol (a Result has .keys() = column names) and subscripts it → "CursorResult is not subscriptable". Materialize with .all() so dict() consumes rows as key-value pairs. The API path already did this; the snapshot task missed it. Caught by test_snapshot_records_timeseries_point (run 1628). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa --- backend/app/tasks/maintenance.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/app/tasks/maintenance.py b/backend/app/tasks/maintenance.py index ddf9e08..e9e334e 100644 --- a/backend/app/tasks/maintenance.py +++ b/backend/app/tasks/maintenance.py @@ -882,18 +882,22 @@ def snapshot_head_metrics() -> int: ) ) } + # .all() first: dict() of a bare Result tries the mapping protocol (a + # Result exposes .keys()) and subscripts it, which fails. applied = dict( session.execute( select(image_tag.c.tag_id, func.count()) .where(image_tag.c.source == "head_auto") .group_by(image_tag.c.tag_id) - ) + ).all() ) tag_ids = set(heads) | set(metrics) if not tag_ids: return 0 names = dict( - session.execute(select(Tag.id, Tag.name).where(Tag.id.in_(tag_ids))) + session.execute( + select(Tag.id, Tag.name).where(Tag.id.in_(tag_ids)) + ).all() ) for tid in tag_ids: h = heads.get(tid)