connection.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from asgiref.local import Local
  2. from django.conf import settings as django_settings
  3. from django.utils.functional import cached_property
  4. class ConnectionProxy:
  5. """Proxy for accessing a connection object's attributes."""
  6. def __init__(self, connections, alias):
  7. self.__dict__['_connections'] = connections
  8. self.__dict__['_alias'] = alias
  9. def __getattr__(self, item):
  10. return getattr(self._connections[self._alias], item)
  11. def __setattr__(self, name, value):
  12. return setattr(self._connections[self._alias], name, value)
  13. def __delattr__(self, name):
  14. return delattr(self._connections[self._alias], name)
  15. def __contains__(self, key):
  16. return key in self._connections[self._alias]
  17. def __eq__(self, other):
  18. return self._connections[self._alias] == other
  19. class ConnectionDoesNotExist(Exception):
  20. pass
  21. class BaseConnectionHandler:
  22. settings_name = None
  23. exception_class = ConnectionDoesNotExist
  24. thread_critical = False
  25. def __init__(self, settings=None):
  26. self._settings = settings
  27. self._connections = Local(self.thread_critical)
  28. @cached_property
  29. def settings(self):
  30. self._settings = self.configure_settings(self._settings)
  31. return self._settings
  32. def configure_settings(self, settings):
  33. if settings is None:
  34. settings = getattr(django_settings, self.settings_name)
  35. return settings
  36. def create_connection(self, alias):
  37. raise NotImplementedError('Subclasses must implement create_connection().')
  38. def __getitem__(self, alias):
  39. try:
  40. return getattr(self._connections, alias)
  41. except AttributeError:
  42. if alias not in self.settings:
  43. raise self.exception_class(f"The connection '{alias}' doesn't exist.")
  44. conn = self.create_connection(alias)
  45. setattr(self._connections, alias, conn)
  46. return conn
  47. def __setitem__(self, key, value):
  48. setattr(self._connections, key, value)
  49. def __delitem__(self, key):
  50. delattr(self._connections, key)
  51. def __iter__(self):
  52. return iter(self.settings)
  53. def all(self):
  54. return [self[alias] for alias in self]