Skip to content

Commit 72582c2

Browse files
authored
Merge pull request #53 from CAVEconnectome/session_fix
improved session management
2 parents 67cefc3 + d895438 commit 72582c2

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

.github/workflows/dynamic_annotation_db _ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ jobs:
3030

3131
steps:
3232
- uses: actions/checkout@v4
33-
- name: Set up Python 3.7
33+
- name: Set up Python 3.12
3434
uses: actions/setup-python@v5
3535
with:
36-
python-version: 3.7
36+
python-version: 3.12
3737

3838
- uses: actions/cache@v4
3939
with:

dynamicannotationdb/database.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,53 @@ def cached_session(self) -> Session:
5555

5656
@contextmanager
5757
def session_scope(self):
58+
session = None
5859
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
6071
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
6277
logging.exception(f"SQL Error: {e}")
6378
raise e
6479
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
67105

68106
def commit_session(self):
69107
try:
@@ -72,9 +110,17 @@ def commit_session(self):
72110
self.cached_session.rollback()
73111
logging.exception(f"SQL Error: {e}")
74112
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
78124

79125
def get_table_sql_metadata(self, table_name: str):
80126
self.base.metadata.reflect(bind=self.engine)

0 commit comments

Comments
 (0)