-
-
Notifications
You must be signed in to change notification settings - Fork 33k
Fixed #36327 -- Added multiple database support to assertNumQueries() #19380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #36327 -- Added multiple database support to assertNumQueries() #19380
Conversation
Please retitle your commit and PR:
https://docs.djangoproject.com/en/dev/internals/contributing/committing-code/#committing-guidelines |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick fly-by review here, after your forum post about this draft
return results | ||
|
||
|
||
class LazyExitStack: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why create this class? Afaict can make a plain ExitStack
during _AssertNumQueriesContext.__enter__
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not work. ExitStack
evaluates the __enter__
method right away. I added a test to demostrate what im trying to accomplish:
def test_deferred(self):
context = self.assertNumQueries(0)
Person.objects.count()
with context:
pass
using ExitStack
: (ps this was a quick and dirty example)
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 8a3e47ed63..fa58471c88 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -102,14 +102,19 @@ class _AssertNumQueriesContext:
def __init__(self, test_case, num, connections_):
self.test_case = test_case
self.num = num
- self.cm = LazyExitStack()
+ # self.cm = LazyExitStack()
+ import contextlib
+ self.cm = contextlib.ExitStack()
+ self.cms = []
for conn in connections_:
- self.cm.enter_context(CaptureQueriesContext(conn))
+ context = CaptureQueriesContext(conn)
+ self.cms.append(context)
+ self.cm.enter_context(context)
@property
def captured_queries(self):
return [
- query for cm in self.cm.context_managers for query in cm.captured_queries
+ query for cm in self.cms for query in cm.captured_queries
]
def __len__(self):
the tests fails:
======================================================================
FAIL: test_deferred (test_utils.tests.AssertNumQueriesContextManagerTests.test_deferred)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/django/source/tests/test_utils/tests.py", line 489, in test_deferred
with context:
^^^^^^^
AssertionError: 1 != 0 : 1 queries executed, 0 expected
Captured queries were:
1. SELECT COUNT(*) AS "__count" FROM "test_utils_person"
----------------------------------------------------------------------
Ran 1 test in 0.004s
…/django into dev/test-multi-db-assert-num
Closing per ticket. |
""" | ||
|
||
def __init__(self): | ||
self.context_managers = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a set.
def enter_context(self, context_manager): | ||
self.context_managers.append(context_manager) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enter_context
is a bad method name. You are registering a context_manager, not entering it. Better: register_context
.
Trac ticket number
ticket-36327
Branch description
The goal is to enhance the behavior of
TestCase.assertNumQueries()
. In large Django projects, the data structure is often split into multiple databases—for example, one for user data, another for business data, one for events, and even a dedicated one for certain monetary compliance logs. As a result, tests may need to validate query counts across several databases. For instance, you might have code that looks like this:The desired improvement is to simplify this syntax. Instead of writing a separate context manager for each database, you could pass multiple databases at once. For example:
Checklist
main
branch.