From fbcaa34b9edb9c7088e630ab7ed337273e6b6d6e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Dec 2008 18:07:35 +0000 Subject: [PATCH] - NullPool supports reconnect on failure behavior. [ticket:1094] --- CHANGES | 3 +++ lib/sqlalchemy/pool.py | 12 ++++++++++++ test/engine/pool.py | 19 +++++++++++++++++++ test/engine/reconnect.py | 19 ++++++++++++++++++- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 2f586bc0af..d1c001ec62 100644 --- a/CHANGES +++ b/CHANGES @@ -143,6 +143,9 @@ CHANGES mapper since it's not needed. - sql + - NullPool supports reconnect on failure behavior. + [ticket:1094] + - Columns can again contain percent signs within their names. [ticket:1256] diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 6aa8b0395d..ee4fa01908 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -695,6 +695,18 @@ class NullPool(Pool): def do_get(self): return self.create_connection() + def recreate(self): + self.log("Pool recreating") + + return NullPool(self._creator, + recycle=self._recycle, + echo=self._should_log_info, + use_threadlocal=self._use_threadlocal, + listeners=self.listeners) + + def dispose(self): + pass + class StaticPool(Pool): """A Pool of exactly one connection, used for all requests. diff --git a/test/engine/pool.py b/test/engine/pool.py index fa8b03b9f9..b712e24128 100644 --- a/test/engine/pool.py +++ b/test/engine/pool.py @@ -572,6 +572,7 @@ class QueuePoolTest(PoolTestBase): def test_reconnect(self): """tests reconnect operations at the pool level. SA's engine/dialect includes another layer of reconnect support for 'database was lost' errors.""" + dbapi = MockDBAPI() p = pool.QueuePool(creator = lambda: dbapi.connect('foo.db'), pool_size = 1, max_overflow = 0, use_threadlocal = False) c1 = p.connect() @@ -642,6 +643,24 @@ class SingletonThreadPoolTest(PoolTestBase): th.join() assert len(p._all_conns) == 3 + +class NullPoolTest(PoolTestBase): + def test_reconnect(self): + dbapi = MockDBAPI() + p = pool.NullPool(creator = lambda: dbapi.connect('foo.db')) + c1 = p.connect() + c_id = c1.connection.id + c1.close(); c1=None + + c1 = p.connect() + dbapi.raise_error = True + c1.invalidate() + c1 = None + + c1 = p.connect() + assert c1.connection.id != c_id + + if __name__ == "__main__": testenv.main() diff --git a/test/engine/reconnect.py b/test/engine/reconnect.py index 64d3fb7943..4f383d2dde 100644 --- a/test/engine/reconnect.py +++ b/test/engine/reconnect.py @@ -1,6 +1,6 @@ import testenv; testenv.configure_for_tests() import weakref -from testlib.sa import select, MetaData, Table, Column, Integer, String +from testlib.sa import select, MetaData, Table, Column, Integer, String, pool import testlib.sa as tsa from testlib import TestBase, testing, engines import time @@ -219,6 +219,23 @@ class RealReconnectTest(TestBase): conn.close() + def test_null_pool(self): + engine = engines.reconnecting_engine(options=dict(poolclass=pool.NullPool)) + conn = engine.connect() + self.assertEquals(conn.execute(select([1])).scalar(), 1) + assert not conn.closed + engine.test_shutdown() + try: + conn.execute(select([1])) + assert False + except tsa.exc.DBAPIError, e: + if not e.connection_invalidated: + raise + assert not conn.closed + assert conn.invalidated + self.assertEquals(conn.execute(select([1])).scalar(), 1) + assert not conn.invalidated + def test_close(self): conn = engine.connect() self.assertEquals(conn.execute(select([1])).scalar(), 1) -- 2.47.3