Fixed #27170 -- Added DatabaseWrapper class attributes to ease subclassing.
This commit is contained in:
parent
0bbab97c28
commit
7ca3b391b6
|
@ -9,9 +9,7 @@ from .schema import MySQLGISSchemaEditor
|
||||||
|
|
||||||
class DatabaseWrapper(MySQLDatabaseWrapper):
|
class DatabaseWrapper(MySQLDatabaseWrapper):
|
||||||
SchemaEditorClass = MySQLGISSchemaEditor
|
SchemaEditorClass = MySQLGISSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
features_class = DatabaseFeatures
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
introspection_class = MySQLIntrospection
|
||||||
self.features = DatabaseFeatures(self)
|
ops_class = MySQLOperations
|
||||||
self.ops = MySQLOperations(self)
|
|
||||||
self.introspection = MySQLIntrospection(self)
|
|
||||||
|
|
|
@ -9,9 +9,7 @@ from .schema import OracleGISSchemaEditor
|
||||||
|
|
||||||
class DatabaseWrapper(OracleDatabaseWrapper):
|
class DatabaseWrapper(OracleDatabaseWrapper):
|
||||||
SchemaEditorClass = OracleGISSchemaEditor
|
SchemaEditorClass = OracleGISSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
features_class = DatabaseFeatures
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
introspection_class = OracleIntrospection
|
||||||
self.features = DatabaseFeatures(self)
|
ops_class = OracleOperations
|
||||||
self.ops = OracleOperations(self)
|
|
||||||
self.introspection = OracleIntrospection(self)
|
|
||||||
|
|
|
@ -17,6 +17,11 @@ from .schema import SpatialiteSchemaEditor
|
||||||
|
|
||||||
class DatabaseWrapper(SQLiteDatabaseWrapper):
|
class DatabaseWrapper(SQLiteDatabaseWrapper):
|
||||||
SchemaEditorClass = SpatialiteSchemaEditor
|
SchemaEditorClass = SpatialiteSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
|
client_class = SpatiaLiteClient
|
||||||
|
features_class = DatabaseFeatures
|
||||||
|
introspection_class = SpatiaLiteIntrospection
|
||||||
|
ops_class = SpatiaLiteOperations
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# Before we get too far, make sure pysqlite 2.5+ is installed.
|
# Before we get too far, make sure pysqlite 2.5+ is installed.
|
||||||
|
@ -37,10 +42,6 @@ class DatabaseWrapper(SQLiteDatabaseWrapper):
|
||||||
'SPATIALITE_LIBRARY_PATH in your settings.'
|
'SPATIALITE_LIBRARY_PATH in your settings.'
|
||||||
)
|
)
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
||||||
self.features = DatabaseFeatures(self)
|
|
||||||
self.ops = SpatiaLiteOperations(self)
|
|
||||||
self.client = SpatiaLiteClient(self)
|
|
||||||
self.introspection = SpatiaLiteIntrospection(self)
|
|
||||||
|
|
||||||
def get_new_connection(self, conn_params):
|
def get_new_connection(self, conn_params):
|
||||||
conn = super(DatabaseWrapper, self).get_new_connection(conn_params)
|
conn = super(DatabaseWrapper, self).get_new_connection(conn_params)
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
from django.db.backends import utils
|
from django.db.backends import utils
|
||||||
|
from django.db.backends.base.validation import BaseDatabaseValidation
|
||||||
from django.db.backends.signals import connection_created
|
from django.db.backends.signals import connection_created
|
||||||
from django.db.transaction import TransactionManagementError
|
from django.db.transaction import TransactionManagementError
|
||||||
from django.db.utils import DatabaseError, DatabaseErrorWrapper
|
from django.db.utils import DatabaseError, DatabaseErrorWrapper
|
||||||
|
@ -36,6 +37,13 @@ class BaseDatabaseWrapper(object):
|
||||||
ops = None
|
ops = None
|
||||||
vendor = 'unknown'
|
vendor = 'unknown'
|
||||||
SchemaEditorClass = None
|
SchemaEditorClass = None
|
||||||
|
# Classes instantiated in __init__().
|
||||||
|
client_class = None
|
||||||
|
creation_class = None
|
||||||
|
features_class = None
|
||||||
|
introspection_class = None
|
||||||
|
ops_class = None
|
||||||
|
validation_class = BaseDatabaseValidation
|
||||||
|
|
||||||
queries_limit = 9000
|
queries_limit = 9000
|
||||||
|
|
||||||
|
@ -88,6 +96,13 @@ class BaseDatabaseWrapper(object):
|
||||||
# is called?
|
# is called?
|
||||||
self.run_commit_hooks_on_set_autocommit_on = False
|
self.run_commit_hooks_on_set_autocommit_on = False
|
||||||
|
|
||||||
|
self.client = self.client_class(self)
|
||||||
|
self.creation = self.creation_class(self)
|
||||||
|
self.features = self.features_class(self)
|
||||||
|
self.introspection = self.introspection_class(self)
|
||||||
|
self.ops = self.ops_class(self)
|
||||||
|
self.validation = self.validation_class(self)
|
||||||
|
|
||||||
def ensure_timezone(self):
|
def ensure_timezone(self):
|
||||||
"""
|
"""
|
||||||
Ensure the connection's timezone is set to `self.timezone_name` and
|
Ensure the connection's timezone is set to `self.timezone_name` and
|
||||||
|
|
|
@ -13,7 +13,6 @@ from django.db.backends.base.client import BaseDatabaseClient
|
||||||
from django.db.backends.base.creation import BaseDatabaseCreation
|
from django.db.backends.base.creation import BaseDatabaseCreation
|
||||||
from django.db.backends.base.introspection import BaseDatabaseIntrospection
|
from django.db.backends.base.introspection import BaseDatabaseIntrospection
|
||||||
from django.db.backends.base.operations import BaseDatabaseOperations
|
from django.db.backends.base.operations import BaseDatabaseOperations
|
||||||
from django.db.backends.base.validation import BaseDatabaseValidation
|
|
||||||
from django.db.backends.dummy.features import DummyDatabaseFeatures
|
from django.db.backends.dummy.features import DummyDatabaseFeatures
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,16 +70,12 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
_savepoint_commit = complain
|
_savepoint_commit = complain
|
||||||
_savepoint_rollback = ignore
|
_savepoint_rollback = ignore
|
||||||
_set_autocommit = complain
|
_set_autocommit = complain
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
client_class = DatabaseClient
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
creation_class = DatabaseCreation
|
||||||
|
features_class = DummyDatabaseFeatures
|
||||||
self.features = DummyDatabaseFeatures(self)
|
introspection_class = DatabaseIntrospection
|
||||||
self.ops = DatabaseOperations(self)
|
ops_class = DatabaseOperations
|
||||||
self.client = DatabaseClient(self)
|
|
||||||
self.creation = DatabaseCreation(self)
|
|
||||||
self.introspection = DatabaseIntrospection(self)
|
|
||||||
self.validation = BaseDatabaseValidation(self)
|
|
||||||
|
|
||||||
def is_usable(self):
|
def is_usable(self):
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -227,16 +227,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
|
||||||
Database = Database
|
Database = Database
|
||||||
SchemaEditorClass = DatabaseSchemaEditor
|
SchemaEditorClass = DatabaseSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
client_class = DatabaseClient
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
creation_class = DatabaseCreation
|
||||||
|
features_class = DatabaseFeatures
|
||||||
self.features = DatabaseFeatures(self)
|
introspection_class = DatabaseIntrospection
|
||||||
self.ops = DatabaseOperations(self)
|
ops_class = DatabaseOperations
|
||||||
self.client = DatabaseClient(self)
|
validation_class = DatabaseValidation
|
||||||
self.creation = DatabaseCreation(self)
|
|
||||||
self.introspection = DatabaseIntrospection(self)
|
|
||||||
self.validation = DatabaseValidation(self)
|
|
||||||
|
|
||||||
def get_connection_params(self):
|
def get_connection_params(self):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import warnings
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import utils
|
from django.db import utils
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||||
from django.db.backends.base.validation import BaseDatabaseValidation
|
|
||||||
from django.utils import six, timezone
|
from django.utils import six, timezone
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
from django.utils.duration import duration_string
|
from django.utils.duration import duration_string
|
||||||
|
@ -179,18 +178,17 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
|
||||||
Database = Database
|
Database = Database
|
||||||
SchemaEditorClass = DatabaseSchemaEditor
|
SchemaEditorClass = DatabaseSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
|
client_class = DatabaseClient
|
||||||
|
creation_class = DatabaseCreation
|
||||||
|
features_class = DatabaseFeatures
|
||||||
|
introspection_class = DatabaseIntrospection
|
||||||
|
ops_class = DatabaseOperations
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.features = DatabaseFeatures(self)
|
|
||||||
use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True)
|
use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True)
|
||||||
self.features.can_return_id_from_insert = use_returning_into
|
self.features.can_return_id_from_insert = use_returning_into
|
||||||
self.ops = DatabaseOperations(self)
|
|
||||||
self.client = DatabaseClient(self)
|
|
||||||
self.creation = DatabaseCreation(self)
|
|
||||||
self.introspection = DatabaseIntrospection(self)
|
|
||||||
self.validation = BaseDatabaseValidation(self)
|
|
||||||
|
|
||||||
def _connect_string(self):
|
def _connect_string(self):
|
||||||
settings_dict = self.settings_dict
|
settings_dict = self.settings_dict
|
||||||
|
|
|
@ -10,7 +10,6 @@ from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||||
from django.db.backends.base.validation import BaseDatabaseValidation
|
|
||||||
from django.db.utils import DatabaseError as WrappedDatabaseError
|
from django.db.utils import DatabaseError as WrappedDatabaseError
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
@ -141,16 +140,12 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
|
||||||
Database = Database
|
Database = Database
|
||||||
SchemaEditorClass = DatabaseSchemaEditor
|
SchemaEditorClass = DatabaseSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
client_class = DatabaseClient
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
creation_class = DatabaseCreation
|
||||||
|
features_class = DatabaseFeatures
|
||||||
self.features = DatabaseFeatures(self)
|
introspection_class = DatabaseIntrospection
|
||||||
self.ops = DatabaseOperations(self)
|
ops_class = DatabaseOperations
|
||||||
self.client = DatabaseClient(self)
|
|
||||||
self.creation = DatabaseCreation(self)
|
|
||||||
self.introspection = DatabaseIntrospection(self)
|
|
||||||
self.validation = BaseDatabaseValidation(self)
|
|
||||||
|
|
||||||
def get_connection_params(self):
|
def get_connection_params(self):
|
||||||
settings_dict = self.settings_dict
|
settings_dict = self.settings_dict
|
||||||
|
|
|
@ -15,7 +15,6 @@ from django.conf import settings
|
||||||
from django.db import utils
|
from django.db import utils
|
||||||
from django.db.backends import utils as backend_utils
|
from django.db.backends import utils as backend_utils
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||||
from django.db.backends.base.validation import BaseDatabaseValidation
|
|
||||||
from django.utils import six, timezone
|
from django.utils import six, timezone
|
||||||
from django.utils.dateparse import (
|
from django.utils.dateparse import (
|
||||||
parse_date, parse_datetime, parse_duration, parse_time,
|
parse_date, parse_datetime, parse_duration, parse_time,
|
||||||
|
@ -163,16 +162,12 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
|
||||||
Database = Database
|
Database = Database
|
||||||
SchemaEditorClass = DatabaseSchemaEditor
|
SchemaEditorClass = DatabaseSchemaEditor
|
||||||
|
# Classes instantiated in __init__().
|
||||||
def __init__(self, *args, **kwargs):
|
client_class = DatabaseClient
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
creation_class = DatabaseCreation
|
||||||
|
features_class = DatabaseFeatures
|
||||||
self.features = DatabaseFeatures(self)
|
introspection_class = DatabaseIntrospection
|
||||||
self.ops = DatabaseOperations(self)
|
ops_class = DatabaseOperations
|
||||||
self.client = DatabaseClient(self)
|
|
||||||
self.creation = DatabaseCreation(self)
|
|
||||||
self.introspection = DatabaseIntrospection(self)
|
|
||||||
self.validation = BaseDatabaseValidation(self)
|
|
||||||
|
|
||||||
def get_connection_params(self):
|
def get_connection_params(self):
|
||||||
settings_dict = self.settings_dict
|
settings_dict = self.settings_dict
|
||||||
|
|
|
@ -32,6 +32,31 @@ from django.utils.six.moves import range
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseWrapperTests(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_initialization_class_attributes(self):
|
||||||
|
"""
|
||||||
|
The "initialization" class attributes like client_class and
|
||||||
|
creation_class should be set on the class and reflected in the
|
||||||
|
corresponding instance attributes of the instantiated backend.
|
||||||
|
"""
|
||||||
|
conn = connections[DEFAULT_DB_ALIAS]
|
||||||
|
conn_class = type(conn)
|
||||||
|
attr_names = [
|
||||||
|
('client_class', 'client'),
|
||||||
|
('creation_class', 'creation'),
|
||||||
|
('features_class', 'features'),
|
||||||
|
('introspection_class', 'introspection'),
|
||||||
|
('ops_class', 'ops'),
|
||||||
|
('validation_class', 'validation'),
|
||||||
|
]
|
||||||
|
for class_attr_name, instance_attr_name in attr_names:
|
||||||
|
class_attr_value = getattr(conn_class, class_attr_name)
|
||||||
|
self.assertIsNotNone(class_attr_value)
|
||||||
|
instance_attr_value = getattr(conn, instance_attr_name)
|
||||||
|
self.assertIsInstance(instance_attr_value, class_attr_value)
|
||||||
|
|
||||||
|
|
||||||
class DummyBackendTest(SimpleTestCase):
|
class DummyBackendTest(SimpleTestCase):
|
||||||
|
|
||||||
def test_no_databases(self):
|
def test_no_databases(self):
|
||||||
|
|
|
@ -281,7 +281,7 @@ class SetupDatabasesTests(unittest.TestCase):
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
|
with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
|
||||||
with mock.patch('django.test.utils.connections', new=tested_connections):
|
with mock.patch('django.test.utils.connections', new=tested_connections):
|
||||||
old_config = self.runner_instance.setup_databases()
|
old_config = self.runner_instance.setup_databases()
|
||||||
self.runner_instance.teardown_databases(old_config)
|
self.runner_instance.teardown_databases(old_config)
|
||||||
|
@ -306,7 +306,7 @@ class SetupDatabasesTests(unittest.TestCase):
|
||||||
'ENGINE': 'django.db.backends.dummy',
|
'ENGINE': 'django.db.backends.dummy',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
|
with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
|
||||||
with mock.patch('django.test.utils.connections', new=tested_connections):
|
with mock.patch('django.test.utils.connections', new=tested_connections):
|
||||||
self.runner_instance.setup_databases()
|
self.runner_instance.setup_databases()
|
||||||
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
|
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
|
||||||
|
@ -320,7 +320,7 @@ class SetupDatabasesTests(unittest.TestCase):
|
||||||
'TEST': {'SERIALIZE': False},
|
'TEST': {'SERIALIZE': False},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
|
with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
|
||||||
with mock.patch('django.test.utils.connections', new=tested_connections):
|
with mock.patch('django.test.utils.connections', new=tested_connections):
|
||||||
self.runner_instance.setup_databases()
|
self.runner_instance.setup_databases()
|
||||||
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
|
mocked_db_creation.return_value.create_test_db.assert_called_once_with(
|
||||||
|
|
Loading…
Reference in New Issue