Fixed DatabaseFeatures.uses_savepoints/can_release_savepoints and related tests with MyISAM storage engine.

This commit is contained in:
Mariusz Felisiak 2022-04-14 09:53:31 +02:00
parent e12670016b
commit 331a460f8f
6 changed files with 14 additions and 5 deletions

View File

@ -305,6 +305,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"""
return self._mysql_storage_engine != "MyISAM"
uses_savepoints = property(operator.attrgetter("supports_transactions"))
can_release_savepoints = property(operator.attrgetter("supports_transactions"))
@cached_property
def ignores_table_name_case(self):
return self.connection.mysql_server_data["lower_case_table_names"]

View File

@ -30,6 +30,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core import mail
from django.core.checks import Error
from django.core.files import temp as tempfile
from django.db import connection
from django.forms.utils import ErrorList
from django.template.response import TemplateResponse
from django.test import (
@ -7022,7 +7023,8 @@ class UserAdminTest(TestCase):
# Don't depend on a warm cache, see #17377.
ContentType.objects.clear_cache()
with self.assertNumQueries(10):
expected_num_queries = 10 if connection.features.uses_savepoints else 8
with self.assertNumQueries(expected_num_queries):
response = self.client.get(reverse("admin:auth_user_change", args=(u.pk,)))
self.assertEqual(response.status_code, 200)
@ -7069,7 +7071,8 @@ class GroupAdminTest(TestCase):
# Ensure no queries are skipped due to cached content type for Group.
ContentType.objects.clear_cache()
with self.assertNumQueries(8):
expected_num_queries = 8 if connection.features.uses_savepoints else 6
with self.assertNumQueries(expected_num_queries):
response = self.client.get(reverse("admin:auth_group_change", args=(g.pk,)))
self.assertEqual(response.status_code, 200)

View File

@ -11,6 +11,7 @@ class TestFeatures(TestCase):
"""
All storage engines except MyISAM support transactions.
"""
del connection.features.supports_transactions
with mock.patch(
"django.db.connection.features._mysql_storage_engine", "InnoDB"
):

View File

@ -291,7 +291,7 @@ class SelectForUpdateTests(TransactionTestCase):
qs = Person.objects.select_for_update(of=("self", "born"))
self.assertIs(qs.exists(), True)
@skipUnlessDBFeature("has_select_for_update_nowait")
@skipUnlessDBFeature("has_select_for_update_nowait", "supports_transactions")
def test_nowait_raises_error_on_block(self):
"""
If nowait is specified, we expect an error to be raised rather
@ -312,7 +312,7 @@ class SelectForUpdateTests(TransactionTestCase):
self.end_blocking_transaction()
self.assertIsInstance(status[-1], DatabaseError)
@skipUnlessDBFeature("has_select_for_update_skip_locked")
@skipUnlessDBFeature("has_select_for_update_skip_locked", "supports_transactions")
def test_skip_locked_skips_locked_rows(self):
"""
If skip_locked is specified, the locked row is skipped resulting in
@ -599,7 +599,7 @@ class SelectForUpdateTests(TransactionTestCase):
p = Person.objects.get(pk=self.person.pk)
self.assertEqual("Fred", p.name)
@skipUnlessDBFeature("has_select_for_update")
@skipUnlessDBFeature("has_select_for_update", "supports_transactions")
def test_raw_lock_not_available(self):
"""
Running a raw query which can't obtain a FOR UPDATE lock raises

View File

@ -8,6 +8,7 @@ class ForcedError(Exception):
pass
@skipUnlessDBFeature("supports_transactions")
class TestConnectionOnCommit(TransactionTestCase):
"""
Tests for transaction.on_commit().

View File

@ -370,6 +370,7 @@ class AtomicErrorsTests(TransactionTestCase):
self.assertEqual(Reporter.objects.count(), 0)
@skipUnlessDBFeature("uses_savepoints")
@skipUnless(connection.vendor == "mysql", "MySQL-specific behaviors")
class AtomicMySQLTests(TransactionTestCase):