@@ -322,11 +322,18 @@ async def get_async_session_with_tenant(
322
322
def get_session_with_tenant (
323
323
tenant_id : str | None = None ,
324
324
) -> Generator [Session , None , None ]:
325
- """Generate a database session bound to a connection with the appropriate tenant schema set."""
325
+ """
326
+ Generate a database session bound to a connection with the appropriate tenant schema set.
327
+ This preserves the tenant ID across the session and reverts to the previous tenant ID
328
+ after the session is closed.
329
+ """
326
330
engine = get_sqlalchemy_engine ()
327
331
332
+ # Store the previous tenant ID
333
+ previous_tenant_id = CURRENT_TENANT_ID_CONTEXTVAR .get ()
334
+
328
335
if tenant_id is None :
329
- tenant_id = CURRENT_TENANT_ID_CONTEXTVAR . get ()
336
+ tenant_id = previous_tenant_id
330
337
else :
331
338
CURRENT_TENANT_ID_CONTEXTVAR .set (tenant_id )
332
339
@@ -335,30 +342,35 @@ def get_session_with_tenant(
335
342
if not is_valid_schema_name (tenant_id ):
336
343
raise HTTPException (status_code = 400 , detail = "Invalid tenant ID" )
337
344
338
- # Establish a raw connection
339
- with engine .connect () as connection :
340
- # Access the raw DBAPI connection and set the search_path
341
- dbapi_connection = connection .connection
342
-
343
- # Set the search_path outside of any transaction
344
- cursor = dbapi_connection .cursor ()
345
- try :
346
- cursor .execute (f'SET search_path = "{ tenant_id } "' )
347
- finally :
348
- cursor .close ()
345
+ try :
346
+ # Establish a raw connection
347
+ with engine .connect () as connection :
348
+ # Access the raw DBAPI connection and set the search_path
349
+ dbapi_connection = connection .connection
349
350
350
- # Bind the session to the connection
351
- with Session ( bind = connection , expire_on_commit = False ) as session :
351
+ # Set the search_path outside of any transaction
352
+ cursor = dbapi_connection . cursor ()
352
353
try :
353
- yield session
354
+ cursor . execute ( f'SET search_path = " { tenant_id } "' )
354
355
finally :
355
- # Reset search_path to default after the session is used
356
- if MULTI_TENANT :
357
- cursor = dbapi_connection .cursor ()
358
- try :
359
- cursor .execute ('SET search_path TO "$user", public' )
360
- finally :
361
- cursor .close ()
356
+ cursor .close ()
357
+
358
+ # Bind the session to the connection
359
+ with Session (bind = connection , expire_on_commit = False ) as session :
360
+ try :
361
+ yield session
362
+ finally :
363
+ # Reset search_path to default after the session is used
364
+ if MULTI_TENANT :
365
+ cursor = dbapi_connection .cursor ()
366
+ try :
367
+ cursor .execute ('SET search_path TO "$user", public' )
368
+ finally :
369
+ cursor .close ()
370
+
371
+ finally :
372
+ # Restore the previous tenant ID
373
+ CURRENT_TENANT_ID_CONTEXTVAR .set (previous_tenant_id )
362
374
363
375
364
376
def set_search_path_on_checkout (
0 commit comments