From 2e66cabe8d90a26ecd8db23d9b6d9cda46a67532 Mon Sep 17 00:00:00 2001 From: Min RK Date: Wed, 23 Jul 2025 09:04:16 -0700 Subject: [PATCH] GET /users: make sure there's always a join on Spawner needed for contains_eager --- jupyterhub/apihandlers/users.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py index 48cc107c..99ac8452 100644 --- a/jupyterhub/apihandlers/users.py +++ b/jupyterhub/apihandlers/users.py @@ -162,12 +162,15 @@ class UserListAPIHandler(APIHandler): ) elif state_filter: raise web.HTTPError(400, f"Unrecognized state filter: {state_filter!r}") + else: + # need a join on Spawner for contains_eager below + query = query.outerjoin(orm.Spawner, orm.User._orm_spawners) # apply eager load options query = query.options( selectinload(orm.User.roles), selectinload(orm.User.groups), - contains_eager(orm.User._orm_spawners).joinedload(orm.Spawner.user), + contains_eager(orm.User._orm_spawners).contains_eager(orm.Spawner.user), # raiseload here helps us make sure we've loaded everything in one query # but since we share a single db session, we can't do this for real # but it's useful in testing