From: Mike Bayer Date: Mon, 14 Sep 2020 14:14:48 +0000 (-0400) Subject: Pass all pool parameters in recreate() X-Git-Tag: rel_1_3_20~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d4c15a8da2e9d30d84fbe1cef3e45832a64bf96;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Pass all pool parameters in recreate() The following pool parameters were not being propagated to the new pool created when :meth:`_engine.Engine.dispose` were called: ``pre_ping``, ``use_lifo``. Additionally the ``recycle`` and ``reset_on_return`` parameters were not propagated for the :class:`_engine.AssertionPool` class. These issues have been fixed. Fixes: #5582 Change-Id: Ifdb703aa7e849652242b9ff8071c854cd1d77e71 (cherry picked from commit 3d803a8ed3e07332dff872180680bed6175dd483) --- diff --git a/doc/build/changelog/unreleased_13/5582.rst b/doc/build/changelog/unreleased_13/5582.rst new file mode 100644 index 0000000000..dca8855d61 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5582.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, pool + :tickets: 5582 + + The following pool parameters were not being propagated to the new pool + created when :meth:`_engine.Engine.dispose` were called: ``pre_ping``, + ``use_lifo``. Additionally the ``recycle`` and ``reset_on_return`` + parameters were not propagated for the :class:`_engine.AssertionPool` + class. These issues have been fixed. diff --git a/lib/sqlalchemy/pool/impl.py b/lib/sqlalchemy/pool/impl.py index 0816a99dde..4ff144203f 100644 --- a/lib/sqlalchemy/pool/impl.py +++ b/lib/sqlalchemy/pool/impl.py @@ -166,6 +166,8 @@ class QueuePool(Pool): self._creator, pool_size=self._pool.maxsize, max_overflow=self._max_overflow, + pre_ping=self._pre_ping, + use_lifo=self._pool.use_lifo, timeout=self._timeout, recycle=self._recycle, echo=self.echo, @@ -248,6 +250,7 @@ class NullPool(Pool): logging_name=self._orig_logging_name, use_threadlocal=self._use_threadlocal, reset_on_return=self._reset_on_return, + pre_ping=self._pre_ping, _dispatch=self.dispatch, dialect=self._dialect, ) @@ -301,6 +304,7 @@ class SingletonThreadPool(Pool): pool_size=self.size, recycle=self._recycle, echo=self.echo, + pre_ping=self._pre_ping, logging_name=self._orig_logging_name, use_threadlocal=self._use_threadlocal, reset_on_return=self._reset_on_return, @@ -403,6 +407,7 @@ class StaticPool(Pool): recycle=self._recycle, use_threadlocal=self._use_threadlocal, reset_on_return=self._reset_on_return, + pre_ping=self._pre_ping, echo=self.echo, logging_name=self._orig_logging_name, _dispatch=self.dispatch, @@ -456,6 +461,9 @@ class AssertionPool(Pool): return self.__class__( self._creator, echo=self.echo, + pre_ping=self._pre_ping, + recycle=self._recycle, + reset_on_return=self._reset_on_return, logging_name=self._orig_logging_name, _dispatch=self.dispatch, dialect=self._dialect, diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py index 51d1b3eb48..3b989959ec 100644 --- a/test/engine/test_pool.py +++ b/test/engine/test_pool.py @@ -9,6 +9,7 @@ from sqlalchemy import event from sqlalchemy import pool from sqlalchemy import select from sqlalchemy import testing +from sqlalchemy.engine import default from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_context_ok from sqlalchemy.testing import assert_raises_message @@ -17,6 +18,7 @@ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_not from sqlalchemy.testing import is_true +from sqlalchemy.testing import mock from sqlalchemy.testing.engines import testing_engine from sqlalchemy.testing.mock import ANY from sqlalchemy.testing.mock import call @@ -25,7 +27,6 @@ from sqlalchemy.testing.mock import patch from sqlalchemy.testing.util import gc_collect from sqlalchemy.testing.util import lazy_gc - join_timeout = 10 @@ -220,6 +221,60 @@ class PoolTest(PoolTestBase): eq_(c2.mock_calls, []) + @testing.combinations( + ( + pool.QueuePool, + dict(pool_size=8, max_overflow=10, timeout=25, use_lifo=True), + ), + (pool.QueuePool, {}), + (pool.NullPool, {}), + (pool.SingletonThreadPool, {}), + (pool.StaticPool, {}), + (pool.AssertionPool, {}), + ) + def test_recreate_state(self, pool_cls, pool_args): + creator = object() + pool_args["pre_ping"] = True + pool_args["reset_on_return"] = "commit" + pool_args["recycle"] = 35 + pool_args["logging_name"] = "somepool" + pool_args["dialect"] = default.DefaultDialect() + pool_args["echo"] = "debug" + + p1 = pool_cls(creator=creator, **pool_args) + + cls_keys = dir(pool_cls) + + d1 = dict(p1.__dict__) + + p2 = p1.recreate() + + d2 = dict(p2.__dict__) + + for k in cls_keys: + d1.pop(k, None) + d2.pop(k, None) + + for k in ( + "_threadconns", + "_invoke_creator", + "_pool", + "_overflow_lock", + "_fairy", + "_conn", + "logger", + ): + if k in d2: + d2[k] = mock.ANY + + eq_(d1, d2) + + eq_(p1.echo, p2.echo) + is_(p1._dialect, p2._dialect) + + if "use_lifo" in pool_args: + eq_(p1._pool.use_lifo, p2._pool.use_lifo) + class PoolDialectTest(PoolTestBase): def _dialect(self):