summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Apolloner <florian@apolloner.eu>2022-03-08 11:48:56 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-03-17 07:40:57 +0100
commit4f92cf87b013801810226928ddd20097f6e4fccf (patch)
tree2b29b4ae2bdd0b8adeaa03ef07ba4d66a5780b2d
parent13378ad95206a96c3d1d261eb738032468a7acc1 (diff)
Prevented initialization of unused database connections.
-rw-r--r--django/contrib/postgres/apps.py2
-rw-r--r--django/core/cache/__init__.py8
-rw-r--r--django/core/handlers/base.py9
-rw-r--r--django/db/__init__.py4
-rw-r--r--django/test/signals.py2
-rw-r--r--django/test/testcases.py4
-rw-r--r--django/utils/connection.py9
-rw-r--r--tests/utils_tests/test_connection.py4
8 files changed, 20 insertions, 22 deletions
diff --git a/django/contrib/postgres/apps.py b/django/contrib/postgres/apps.py
index d917201f05..79fbe57c8f 100644
--- a/django/contrib/postgres/apps.py
+++ b/django/contrib/postgres/apps.py
@@ -51,7 +51,7 @@ class PostgresConfig(AppConfig):
def ready(self):
setting_changed.connect(uninstall_if_needed)
# Connections may already exist before we are called.
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
if conn.vendor == "postgresql":
conn.introspection.data_types_reverse.update(
{
diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index f09c9ecc4b..613d3632ed 100644
--- a/django/core/cache/__init__.py
+++ b/django/core/cache/__init__.py
@@ -51,14 +51,6 @@ class CacheHandler(BaseConnectionHandler):
) from e
return backend_cls(location, params)
- def all(self, initialized_only=False):
- return [
- self[alias]
- for alias in self
- # If initialized_only is True, return only initialized caches.
- if not initialized_only or hasattr(self._connections, alias)
- ]
-
caches = CacheHandler()
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index caee168cbf..a934659186 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -344,16 +344,13 @@ class BaseHandler:
def make_view_atomic(self, view):
non_atomic_requests = getattr(view, "_non_atomic_requests", set())
- for db in connections.all():
- if (
- db.settings_dict["ATOMIC_REQUESTS"]
- and db.alias not in non_atomic_requests
- ):
+ for alias, settings_dict in connections.settings.items():
+ if settings_dict["ATOMIC_REQUESTS"] and alias not in non_atomic_requests:
if asyncio.iscoroutinefunction(view):
raise RuntimeError(
"You cannot use ATOMIC_REQUESTS with async views."
)
- view = transaction.atomic(using=db.alias)(view)
+ view = transaction.atomic(using=alias)(view)
return view
def process_exception_by_middleware(self, exception, request):
diff --git a/django/db/__init__.py b/django/db/__init__.py
index b0cae97e01..f3cf4574a9 100644
--- a/django/db/__init__.py
+++ b/django/db/__init__.py
@@ -43,7 +43,7 @@ connection = ConnectionProxy(connections, DEFAULT_DB_ALIAS)
# Register an event to reset saved queries when a Django request is started.
def reset_queries(**kwargs):
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
conn.queries_log.clear()
@@ -53,7 +53,7 @@ signals.request_started.connect(reset_queries)
# Register an event to reset transaction state and close connections past
# their lifetime.
def close_old_connections(**kwargs):
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
conn.close_if_unusable_or_obsolete()
diff --git a/django/test/signals.py b/django/test/signals.py
index c874f220df..75b6339a15 100644
--- a/django/test/signals.py
+++ b/django/test/signals.py
@@ -70,7 +70,7 @@ def update_connections_time_zone(*, setting, **kwargs):
# Reset the database connections' time zone
if setting in {"TIME_ZONE", "USE_TZ"}:
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
try:
del conn.timezone
except AttributeError:
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 3758671117..bfcfef58cb 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -1197,7 +1197,7 @@ class TransactionTestCase(SimpleTestCase):
# tests (e.g., losing a timezone setting causing objects to be
# created with the wrong time). To make sure this doesn't
# happen, get a clean connection at the start of every test.
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
conn.close()
finally:
if self.available_apps is not None:
@@ -1378,7 +1378,7 @@ class TestCase(TransactionTestCase):
def tearDownClass(cls):
if cls._databases_support_transactions():
cls._rollback_atomics(cls.cls_atomics)
- for conn in connections.all():
+ for conn in connections.all(initialized_only=True):
conn.close()
super().tearDownClass()
diff --git a/django/utils/connection.py b/django/utils/connection.py
index 1b5895e8d3..5a82769cfc 100644
--- a/django/utils/connection.py
+++ b/django/utils/connection.py
@@ -72,5 +72,10 @@ class BaseConnectionHandler:
def __iter__(self):
return iter(self.settings)
- def all(self):
- return [self[alias] for alias in self]
+ def all(self, initialized_only=False):
+ return [
+ self[alias]
+ for alias in self
+ # If initialized_only is True, return only initialized connections.
+ if not initialized_only or hasattr(self._connections, alias)
+ ]
diff --git a/tests/utils_tests/test_connection.py b/tests/utils_tests/test_connection.py
index e7d63b8d0f..e1e2bbb28c 100644
--- a/tests/utils_tests/test_connection.py
+++ b/tests/utils_tests/test_connection.py
@@ -8,3 +8,7 @@ class BaseConnectionHandlerTests(SimpleTestCase):
msg = "Subclasses must implement create_connection()."
with self.assertRaisesMessage(NotImplementedError, msg):
handler.create_connection(None)
+
+ def test_all_initialized_only(self):
+ handler = BaseConnectionHandler({"default": {}})
+ self.assertEqual(handler.all(initialized_only=True), [])