summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-04-14 07:53:15 +0200
committerGitHub <noreply@github.com>2022-04-14 07:53:15 +0200
commita0bd0063065de054c73d5984d7b4830e29e809e6 (patch)
treee6bb875b62ce3aced78237c66170adbc2d5b62d1
parentdb83ac48d4015ce3487405481426c3d2d38335df (diff)
Made select_for_update() don't raise TransactionManagementError on databases that don't support transactions.
-rw-r--r--django/db/models/sql/compiler.py7
-rw-r--r--tests/queries/test_explain.py16
-rw-r--r--tests/select_for_update/tests.py4
3 files changed, 12 insertions, 15 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index faa08e376d..1285b647d8 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -653,7 +653,12 @@ class SQLCompiler:
params.extend(f_params)
if self.query.select_for_update and features.has_select_for_update:
- if self.connection.get_autocommit():
+ if (
+ self.connection.get_autocommit()
+ # Don't raise an exception when database doesn't
+ # support transactions, as it's a noop.
+ and features.supports_transactions
+ ):
raise TransactionManagementError(
"select_for_update cannot be used outside of a transaction."
)
diff --git a/tests/queries/test_explain.py b/tests/queries/test_explain.py
index f61fe01e9d..43ff0bdef3 100644
--- a/tests/queries/test_explain.py
+++ b/tests/queries/test_explain.py
@@ -32,19 +32,11 @@ class ExplainTests(TestCase):
for idx, queryset in enumerate(querysets):
for format in all_formats:
with self.subTest(format=format, queryset=idx):
- with CaptureQueriesContext(connection) as captured_queries:
- if queryset.query.select_for_update:
- with transaction.atomic():
- result = queryset.explain(format=format)
- else:
- result = queryset.explain(format=format)
- self.assertEqual(len(captured_queries), 1)
+ with self.assertNumQueries(1) as captured_queries:
+ result = queryset.explain(format=format)
self.assertTrue(
- any(
- captured_query["sql"].startswith(
- connection.ops.explain_prefix
- )
- for captured_query in captured_queries
+ captured_queries[0]["sql"].startswith(
+ connection.ops.explain_prefix
)
)
self.assertIsInstance(result, str)
diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py
index 1612a66064..0251014541 100644
--- a/tests/select_for_update/tests.py
+++ b/tests/select_for_update/tests.py
@@ -491,7 +491,7 @@ class SelectForUpdateTests(TransactionTestCase):
str(Person.objects.filter(name="foo").select_for_update().query),
)
- @skipUnlessDBFeature("has_select_for_update")
+ @skipUnlessDBFeature("has_select_for_update", "supports_transactions")
def test_for_update_requires_transaction(self):
"""
A TransactionManagementError is raised
@@ -501,7 +501,7 @@ class SelectForUpdateTests(TransactionTestCase):
with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
list(Person.objects.select_for_update())
- @skipUnlessDBFeature("has_select_for_update")
+ @skipUnlessDBFeature("has_select_for_update", "supports_transactions")
def test_for_update_requires_transaction_only_in_execution(self):
"""
No TransactionManagementError is raised