@@ -55,15 +55,53 @@ def cached_session(self) -> Session:
55
55
56
56
@contextmanager
57
57
def session_scope (self ):
58
+ session = None
58
59
try :
59
- yield self .cached_session
60
+ # Validate and recreate session if needed
61
+ if self ._cached_session is None or not self ._is_session_valid (self ._cached_session ):
62
+ if self ._cached_session is not None :
63
+ try :
64
+ self ._cached_session .close ()
65
+ except Exception :
66
+ pass
67
+ self ._cached_session = None
68
+
69
+ session = self .cached_session
70
+ yield session
60
71
except Exception as e :
61
- self .cached_session .rollback ()
72
+ if session is not None :
73
+ try :
74
+ session .rollback ()
75
+ except Exception :
76
+ pass
62
77
logging .exception (f"SQL Error: { e } " )
63
78
raise e
64
79
finally :
65
- self .cached_session .close ()
66
- self ._cached_session = None
80
+ # Don't close the session - let connection pool manage it
81
+ # The session will be reused for subsequent requests
82
+ pass
83
+
84
+ def _is_session_valid (self , session : Session ) -> bool :
85
+ """
86
+ Check if a SQLAlchemy session is valid and can be used.
87
+
88
+ Args:
89
+ session (Session): The SQLAlchemy session to validate.
90
+
91
+ Returns:
92
+ bool: True if the session is valid, False otherwise.
93
+ """
94
+ if session is None :
95
+ return False
96
+ try :
97
+ # Check if session is bound and connection is alive
98
+ if not hasattr (session , 'bind' ) or session .bind is None :
99
+ return False
100
+ # Try a simple query to test the connection
101
+ session .get_bind ().execute ("SELECT 1" )
102
+ return True
103
+ except Exception :
104
+ return False
67
105
68
106
def commit_session (self ):
69
107
try :
@@ -72,9 +110,17 @@ def commit_session(self):
72
110
self .cached_session .rollback ()
73
111
logging .exception (f"SQL Error: { e } " )
74
112
raise e
75
- finally :
76
- self .cached_session .close ()
77
- self ._cached_session = None
113
+ # Don't close or reset the session - keep it for reuse
114
+
115
+ def close_session (self ):
116
+ """Explicitly close the cached session (for cleanup/shutdown)."""
117
+ if self ._cached_session is not None :
118
+ try :
119
+ self ._cached_session .close ()
120
+ except Exception as e :
121
+ logging .exception (f"Error closing session: { e } " )
122
+ finally :
123
+ self ._cached_session = None
78
124
79
125
def get_table_sql_metadata (self , table_name : str ):
80
126
self .base .metadata .reflect (bind = self .engine )
0 commit comments