From: Jason Kirtland Date: Wed, 9 May 2007 22:39:50 +0000 (+0000) Subject: - Connections can be detached from their pool, closing on dereference instead of... X-Git-Tag: rel_0_3_8~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98207edf309c58198b6b1700776fc415a6bcac19;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Connections can be detached from their pool, closing on dereference instead of returning to the pool for reuse --- diff --git a/CHANGES b/CHANGES index 1c13273d9d..2e4862d1df 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +- engines + - connections can be detached from their pool, closing on dereference + instead of returning to the pool for reuse - sql - _Label class overrides compare_self to return its ultimate object. meaning, if you say someexpr.label('foo') == 5, it produces diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 9a2cdad0e2..6ad560e5b3 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -260,7 +260,8 @@ class _ConnectionFairy(object): def invalidate(self, e=None): if self.connection is None: raise exceptions.InvalidRequestError("This connection is closed") - self._connection_record.invalidate(e=e) + if self._connection_record is not None: + self._connection_record.invalidate(e=e) self.connection = None self._cursors = None self._close() @@ -282,6 +283,12 @@ class _ConnectionFairy(object): self.__counter +=1 return self + def detach(self): + if self._connection_record is not None: + self._connection_record.connection = None + self._pool.do_return_conn(self._connection_record) + self._connection_record = None + def close_open_cursors(self): if self._cursors is not None: for c in list(self._cursors): @@ -307,6 +314,9 @@ class _ConnectionFairy(object): if self.connection is not None: try: self.connection.rollback() + # Immediately close detached instances + if self._connection_record is None: + self.connection.close() except Exception, e: if self._connection_record is not None: self._connection_record.invalidate(e=e) diff --git a/test/engine/pool.py b/test/engine/pool.py index fdcdce2aa4..315470e98b 100644 --- a/test/engine/pool.py +++ b/test/engine/pool.py @@ -17,9 +17,10 @@ class MockConnection(object): def __init__(self): global mcid self.id = mcid + self.closed = False mcid += 1 def close(self): - pass + self.closed = True def rollback(self): pass def cursor(self): @@ -205,6 +206,30 @@ class PoolTest(PersistTest): c1 = p.connect() assert c1.connection.id != c_id + + def test_detach(self): + dbapi = MockDBAPI() + p = pool.QueuePool(creator = lambda: dbapi.connect('foo.db'), pool_size = 1, max_overflow = 0, use_threadlocal = False) + + c1 = p.connect() + c1.detach() + c_id = c1.connection.id + + c2 = p.connect() + assert c2.connection.id != c1.connection.id + dbapi.raise_error = True + + c2.invalidate() + c2 = None + + c2 = p.connect() + assert c2.connection.id != c1.connection.id + + con = c1.connection + + assert not con.closed + c1.close() + assert con.closed def testthreadlocal_del(self): self._do_testthreadlocal(useclose=False)