123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import logging
- from typing import TYPE_CHECKING
- from django.conf import settings
- from django.db import ProgrammingError
- from . import base_impl
- from .introspection import PostgresIntrospection
- from .operations import PostgresOperations
- from .schema import PostgresSchemaEditor
- from django.db.backends.postgresql.base import ( # isort:skip
- DatabaseWrapper as PostgresDatabaseWrapper,
- )
- logger = logging.getLogger(__name__)
- if TYPE_CHECKING:
- class Wrapper(PostgresDatabaseWrapper):
- pass
- else:
- Wrapper = base_impl.backend()
- class DatabaseWrapper(Wrapper):
- """Wraps the standard PostgreSQL database back-end.
- Overrides the schema editor with our custom schema editor and makes
- sure the `hstore` extension is enabled.
- """
- SchemaEditorClass = PostgresSchemaEditor # type: ignore[assignment]
- introspection_class = PostgresIntrospection
- ops_class = PostgresOperations
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- # Some base back-ends such as the PostGIS back-end don't properly
- # set `ops_class` and `introspection_class` and initialize these
- # classes themselves.
- #
- # This can lead to broken functionality. We fix this automatically.
- if not isinstance(self.introspection, self.introspection_class):
- self.introspection = self.introspection_class(self)
- if not isinstance(self.ops, self.ops_class):
- self.ops = self.ops_class(self)
- for expected_compiler_class in self.ops.compiler_classes:
- compiler_class = self.ops.compiler(expected_compiler_class.__name__)
- if not issubclass(compiler_class, expected_compiler_class):
- logger.warning(
- "Compiler '%s.%s' is not properly deriving from '%s.%s'."
- % (
- compiler_class.__module__,
- compiler_class.__name__,
- expected_compiler_class.__module__,
- expected_compiler_class.__name__,
- )
- )
- def prepare_database(self):
- """Ran to prepare the configured database.
- This is where we enable the `hstore` extension if it wasn't
- enabled yet.
- """
- super().prepare_database()
- setup_ext = getattr(
- settings, "POSTGRES_EXTRA_AUTO_EXTENSION_SET_UP", True
- )
- if not setup_ext:
- return False
- with self.cursor() as cursor:
- try:
- cursor.execute("CREATE EXTENSION IF NOT EXISTS hstore")
- except ProgrammingError: # permission denied
- logger.warning(
- 'Failed to create "hstore" extension. '
- "Tables with hstore columns may fail to migrate. "
- "If hstore is needed, make sure you are connected "
- "to the database as a superuser "
- "or add the extension manually.",
- exc_info=True,
- )
|