base.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import re
  2. from django.conf import settings
  3. from django.core.exceptions import ImproperlyConfigured
  4. from django.db import utils
  5. from django.db.backends import utils as backend_utils
  6. from django.db.backends.base.base import BaseDatabaseWrapper
  7. from django.utils.functional import cached_property
  8. try:
  9. import MySQLdb as Database
  10. import sqlalchemy.pool as pool
  11. from sqlalchemy.exc import TimeoutError
  12. # Database = pool.manage(Database, poolclass=QueuePool, **settings.SQLALCHEMY_QUEUEPOOL)
  13. except ImportError as err:
  14. raise ImproperlyConfigured(
  15. 'Error loading MySQLdb module.\n'
  16. 'Did you install mysqlclient and SQLAlchemy?'
  17. ) from err
  18. from MySQLdb.constants import CLIENT, FIELD_TYPE # isort:skip
  19. from MySQLdb.converters import conversions # isort:skip
  20. # Some of these import MySQLdb, so import them after checking if it's installed.
  21. from django.db.backends.mysql.client import DatabaseClient # isort:skip
  22. from django.db.backends.mysql.creation import DatabaseCreation # isort:skip
  23. from django.db.backends.mysql.features import DatabaseFeatures # isort:skip
  24. from django.db.backends.mysql.introspection import DatabaseIntrospection # isort:skip
  25. from django.db.backends.mysql.operations import DatabaseOperations # isort:skip
  26. from django.db.backends.mysql.schema import DatabaseSchemaEditor # isort:skip
  27. from django.db.backends.mysql.validation import DatabaseValidation # isort:skip
  28. version = Database.version_info
  29. if version < (1, 3, 3):
  30. raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
  31. # MySQLdb returns TIME columns as timedelta -- they are more like timedelta in
  32. # terms of actual behavior as they are signed and include days -- and Django
  33. # expects time.
  34. django_conversions = conversions.copy()
  35. django_conversions.update({
  36. FIELD_TYPE.TIME: backend_utils.typecast_time,
  37. })
  38. # This should match the numerical portion of the version numbers (we can treat
  39. # versions like 5.0.24 and 5.0.24a as the same).
  40. server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
  41. from django.db.backends.mysql.base import CursorWrapper
  42. from django.db.backends.mysql.base import DatabaseWrapper as _DatabaseWrapper
  43. class DatabaseWrapper(_DatabaseWrapper):
  44. def get_new_connection(self, conn_params):
  45. # return a mysql connection
  46. alias = self._get_alias_by_params(conn_params)
  47. new_params = settings.DATABASES[alias]
  48. options = new_params.get('OPTIONS') or {}
  49. database = Database.connect(
  50. host=new_params['HOST'],
  51. port=int(new_params['PORT']),
  52. user=new_params['USER'],
  53. database=new_params['NAME'],
  54. password=new_params['PASSWORD'],
  55. use_unicode=True,
  56. charset=options.get('charset') or 'utf8mb4',
  57. client_flag=conn_params['client_flag'],
  58. sql_mode=options.get('sql_mode') or 'STRICT_TRANS_TABLES',
  59. )
  60. strParameter = "SET SESSION group_concat_max_len = 1000000;"
  61. strParameter = strParameter + "SET SESSION max_execution_time = 30000;"
  62. strParameter = strParameter + "SET SESSION sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';"
  63. with database.cursor() as cursor:
  64. cursor.execute(strParameter)
  65. cursor.close()
  66. return database
  67. def _get_alias_by_params(self, conn_params):
  68. target_str = ''.join([str(conn_params[_]) for _ in ['host', 'port', 'database', 'user', 'password']])
  69. for k, v in settings.DATABASES.items():
  70. _str = ''.join([str(v[_]) for _ in ['HOST', 'PORT', 'NAME', 'USER', 'PASSWORD']])
  71. if _str == target_str:
  72. return k
  73. return 'default'