]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Pass all pool parameters in recreate()
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 14 Sep 2020 14:14:48 +0000 (10:14 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 14 Sep 2020 15:36:31 +0000 (11:36 -0400)
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

doc/build/changelog/unreleased_13/5582.rst [new file with mode: 0644]
lib/sqlalchemy/pool/impl.py
lib/sqlalchemy/util/queue.py
test/engine/test_pool.py

diff --git a/doc/build/changelog/unreleased_13/5582.rst b/doc/build/changelog/unreleased_13/5582.rst
new file mode 100644 (file)
index 0000000..dca8855
--- /dev/null
@@ -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.
index e1a9f00db186e687de442d551c63372281aeeb98..a6c0cf1041dc6a14d73cb11556809b87374ed973 100644 (file)
@@ -168,6 +168,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,
@@ -252,6 +254,7 @@ class NullPool(Pool):
             echo=self.echo,
             logging_name=self._orig_logging_name,
             reset_on_return=self._reset_on_return,
+            pre_ping=self._pre_ping,
             _dispatch=self.dispatch,
             dialect=self._dialect,
         )
@@ -305,6 +308,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,
             reset_on_return=self._reset_on_return,
             _dispatch=self.dispatch,
@@ -406,6 +410,7 @@ class StaticPool(Pool):
             creator=self._creator,
             recycle=self._recycle,
             reset_on_return=self._reset_on_return,
+            pre_ping=self._pre_ping,
             echo=self.echo,
             logging_name=self._orig_logging_name,
             _dispatch=self.dispatch,
@@ -459,6 +464,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,
index 58a88e4ede9e291fcfe91f65b3a5444359fbf0a9..9447abeded74f1ceee19f472a474166c5e951327 100644 (file)
@@ -209,6 +209,7 @@ class AsyncAdaptedQueue:
             self._queue = asyncio.LifoQueue(maxsize=maxsize)
         else:
             self._queue = asyncio.Queue(maxsize=maxsize)
+        self.use_lifo = use_lifo
         self.maxsize = maxsize
         self.empty = self._queue.empty
         self.full = self._queue.full
index 6f5093b06a8f4ca14fd8c035af05ba632c5eb0c6..fbe39423868460edded4bc50238e8223d3b8c55d 100644 (file)
@@ -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):