Database Connection Failing on Upgrade to 4.2.7

To begin, this is my best theory to date. I’m not positive this is the problem and I’m open to being corrected by anyone more knowledgeable.

Summary;
I’m upgrading from Django 3.2 to Django 4.2.7. Everything went fine, I figured out library conflicts and “climbed the ladder” of release numbers, tested and got all unit tests passing. However, when I try to run the application, it fails on connecting to the database with the following error: AttributeError. Did you mean: ‘mysql_server_info’?

Detail:

The error: AttributeError. Did you mean: ‘mysql_server_info’? is coming from here which is the class DatabaseWrapper(BaseDatabaseWrapper)
venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py", line 290, in getattr

The getattr appears to be triggered from here:
venv_Django_4.2.8/lib/python3.11/site-packages/django/db/backends/mysql/features.py", line 228, in is_sql_auto_is_null_enabled
return self.connection.mysql_server_data[“sql_auto_is_null”]

When I look in debug mode, that features.py has a class DatabaseFeatures(BaseDatabaseFeatures): that contains that method: is_sql_auto_is_null_enabled.

However, when the method is called, it hits the getattr because, I assume, the mysql_server_data dictionary is NOT found in the connection object referenced by the call above. (I have verified the dict is not present in debug mode). The connection object is labeled as “DatabaseWrapper” in debug mode and I can see breakpoints being hit in the DatabaseWrapper class mentioned above at runtime.

However - I notice that there is another DatabaseWrapper(BaseDatabaseWrapper): here…
venv_Django_4.2.8/lib/python3.11/site-packages/django/db/backends/mysql/base.py

And this one seems to be creating the exact dictionary that is being called above.
Like this:

@cached_property
    def mysql_server_data(self):
        with self.temporary_connection() as cursor:
            # Select some server variables and test if the time zone
            # definitions are installed. CONVERT_TZ returns NULL if 'UTC'
            # timezone isn't loaded into the mysql.time_zone table.
            cursor.execute(
                """
                SELECT VERSION(),
                       @@sql_mode,
                       @@default_storage_engine,
                       @@sql_auto_is_null,
                       @@lower_case_table_names,
                       CONVERT_TZ('2001-01-01 01:00:00', 'UTC', 'UTC') IS NOT NULL
            """
            )
            row = cursor.fetchone()
        return {
            "version": row[0],
            "sql_mode": row[1],
            "default_storage_engine": row[2],
            "sql_auto_is_null": bool(row[3]),
            "lower_case_table_names": bool(row[4]),
            "has_zoneinfo_database": bool(row[5]),
        }

It also seems to me that the following entry in settings.py is driving the choice of the first connector (DatabaseWrapper) class (venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py)

DATABASES = {
‘default’: {
‘ENGINE’: ‘mysql.connector.django’,

And that maybe, if the other DatabaseWrapper class was used, that dictionary would be present in the “connection” object when it was called in the DatabaseFeatures class…

So, if I’m right - what would be the reason for needing to change that ‘ENGINE’ string in settings.py on an upgrade to Django 4.2? I can’t see anything in the docs for that version… It seems to be the right choice, but, as I’ve described above, it is failing on a non-existent dictionary.

Isn’t the DatabaseWrapper class I’m using for MySQL and Django the correct one?
(venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py)

Any ideas would be appreciated - as I said at the top, this is my best theory at the moment, but I could be wrong.

Thanks

PS: This is the trace…

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 982, in run
    self._target(*self._args, **self._kwargs)
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 136, in inner_run
    self.check_migrations()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 574, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/loader.py", line 58, in __init__
    self.build_graph()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/loader.py", line 235, in build_graph
    self.applied_migrations = recorder.applied_migrations()
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
    if self.has_table():
       ^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/ddtrace/contrib/trace_utils.py", line 341, in wrapper
    return func(mod, pin, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/ddtrace/contrib/django/patch.py", line 120, in cursor
    cursor = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 330, in cursor
    return self._cursor()
           ^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 306, in _cursor
    self.ensure_connection()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection
    self.connect()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 272, in connect
    self.init_connection_state()
  File "/venv_Django_4.2.8/lib/python3.11/site-packages/mysql/connector/django/base.py", line 341, in init_connection_state
    if self.features.is_sql_auto_is_null_enabled:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/mysql/features.py", line 228, in is_sql_auto_is_null_enabled
    return self.connection.mysql_server_data["sql_auto_is_null"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py", line 290, in __getattr__
    raise AttributeError
AttributeError. Did you mean: 'mysql_server_info'?
DATABASES = {
        'default': {
            'ENGINE': 'mysql.connector.django',
            'NAME': os.environ.get('AGENT_DIRECTORY_DATABASE_NAME', 'employee'),
            'USER': os.environ.get('AGENT_DIRECTORY_DATABASE_USER'),
            'PASSWORD': os.environ.get('AGENT_DIRECTORY_DATABSE_PASSWORD'),
            'HOST': os.environ.get('AGENT_DIRECTORY_DATABSE_HOST'),
            'PORT': os.environ.get('AGENT_DIRECTORY_DATABSE_PORT', 3306)
        }
    }

Excellent work in tracking down what you have so far. However, we do request that complete information be provided concerning error conditions.

Please post the complete traceback received along with your complete DATABASES definition. (Each surrounded between lines of three backtick - ` characters.)

Thank you… Trace, DB Config, and code posted with tickmarks. (thanks for the reminder)

Also, I did trace through the magic code that derives the package and file name from the Database config string and can document that as well if necessary, but perhaps it is sufficient to say that the code takes ‘mysql.connector.django’ and turns it into ‘/mysql/connector/django/base’ or similar…

I’d say the problem might be in mysql-connector-python and its DatabaseWrapper either not having the mysql_server_data property defined or having it raising an AttributeError, then falling back to a call to __getattr__ itself raising an AttributeError as shown in the traceback.

As far as I can see in the source code of mysql-connector-python, the line referenced in the traceback does not correspond with the last version of the library.

What is your version of mysql-connector-python ?

Does the issue occur if you use django.db.backends.mysql as the engine in settings ? If not, this would confirm the bug is in mysql-connector-python.

Does upgrading version of mysql-connector-python solve the issue ?

Thank you @antoinehumbert .

I will go find mysql-connector-python and see what I can find…

And thanks for the suggestion of what else to try in the Engine setting - I didn’t know what would fly…

I tried with that as the Engine setting… Same error I’m afraid…

It can’t be exactly the same as the error won’t occur in mysql.connector.django in this case.

Can you share the traceback of error when using django.db.backends.mysql engine ?

Settings:

DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': os.environ.get('AGENT_DIRECTORY_DATABASE_NAME', 'employee'),
            'USER': os.environ.get('AGENT_DIRECTORY_DATABASE_USER'),
            'PASSWORD': os.environ.get('AGENT_DIRECTORY_DATABSE_PASSWORD'),
            'HOST': os.environ.get('AGENT_DIRECTORY_DATABSE_HOST'),
            'PORT': os.environ.get('AGENT_DIRECTORY_DATABSE_PORT', 3306)
        }
    }

Trace:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 982, in run
    self._target(*self._args, **self._kwargs)
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 136, in inner_run
    self.check_migrations()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 574, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/loader.py", line 58, in __init__
    self.build_graph()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/loader.py", line 235, in build_graph
    self.applied_migrations = recorder.applied_migrations()
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
    if self.has_table():
       ^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/ddtrace/contrib/trace_utils.py", line 341, in wrapper
    return func(mod, pin, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/ddtrace/contrib/django/patch.py", line 120, in cursor
    cursor = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 330, in cursor
    return self._cursor()
           ^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 306, in _cursor
    self.ensure_connection()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection
    self.connect()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/base/base.py", line 272, in connect
    self.init_connection_state()
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py", line 341, in init_connection_state
    if self.features.is_sql_auto_is_null_enabled:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/mysql/features.py", line 228, in is_sql_auto_is_null_enabled
    return self.connection.mysql_server_data["sql_auto_is_null"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv_Django_4.2.7/lib/python3.11/site-packages/mysql/connector/django/base.py", line 290, in __getattr__
    raise AttributeError
AttributeError. Did you mean: 'mysql_server_info'?

The traceback is not consistent with the engine used. I guess the modified settings are not those used when issue arise.

What happens if you uninstall mysql-connector-python ?

Dang. Thank you. Let me fix.

You’re right about the settings.

Looks like the magic package loading was unhappy with the config?

Config:

DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'employee',
            'USER': db_credentials.get('username'),
            'PASSWORD': db_credentials.get('password'),
            'HOST': db_credentials.get('host'),
            'PORT': '3306',
            'OPTIONS': {
                'connect_timeout': 30
            }
        }
    }

Trace

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 15, in <module>
    import MySQLdb as Database
ModuleNotFoundError: No module named 'MySQLdb'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 982, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    autoreload.raise_last_exception()
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/core/management/__init__.py", line 394, in execute
    autoreload.check_errors(django.setup)()
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/ddtrace/contrib/trace_utils.py", line 341, in wrapper
    return func(mod, pin, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/ddtrace/contrib/django/patch.py", line 247, in traced_populate
    ret = func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/apps/registry.py", line 116, in populate
    app_config.import_models()
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/apps/config.py", line 269, in import_models
    self.models_module = import_module(models_module_name)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/ddtrace/internal/module.py", line 211, in _exec_module
    self.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/contrib/auth/models.py", line 3, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/ddtrace/internal/module.py", line 211, in _exec_module
    self.loader.exec_module(module)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 57, in <module>
    class AbstractBaseUser(models.Model):
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/models/base.py", line 143, in __new__
    new_class.add_to_class("_meta", Options(meta, app_label))
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/models/base.py", line 371, in add_to_class
    value.contribute_to_class(cls, name)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/models/options.py", line 243, in contribute_to_class
    self.db_table, connection.ops.max_name_length()
                   ^^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/utils/connection.py", line 15, in __getattr__
    return getattr(self._connections[self._alias], item)
                   ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/utils/connection.py", line 62, in __getitem__
    conn = self.create_connection(alias)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/utils.py", line 193, in create_connection
    backend = load_backend(db["ENGINE"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/utils.py", line 113, in load_backend
    return import_module("%s.base" % backend_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/ddtrace/internal/module.py", line 211, in _exec_module
    self.loader.exec_module(module)
  File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 17, in <module>
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

mysql_connector_python-8.0.23.dist-info

That appears to be the mysql_connector_python version

Ok, and after installing mysqlclient ?

Stand by… I’ll get that done

Looking at source code of mysql-connector-python for version 8.0.23, the DatabaseWrapper does not contain property mysql_server_data. Hence, it is not compatible with django 4 (it is not compatible with django 3 too as farcasvI can see).

So, if you want to use mysql-connector-python (do you have any good reason for that ?), you should consider uphrading to a recent version

More fun. Pip was not happy building the “wheel”
Sorry - not familiar with these errors.

Collecting mysqlclient
  Downloading https://nexus3.mgmt-svg.com/repository/svg-python-group/packages/mysqlclient/2.2.1/mysqlclient-2.2.1.tar.gz (89 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 90.0/90.0 kB 979.5 kB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [30 lines of output]
      /bin/sh: pkg-config: command not found
      /bin/sh: pkg-config: command not found
      /bin/sh: pkg-config: command not found
      Trying pkg-config --exists mysqlclient
      Command 'pkg-config --exists mysqlclient' returned non-zero exit status 127.
      Trying pkg-config --exists mariadb
      Command 'pkg-config --exists mariadb' returned non-zero exit status 127.
      Trying pkg-config --exists libmariadb
      Command 'pkg-config --exists libmariadb' returned non-zero exit status 127.
      Traceback (most recent call last):
        File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/john.bickerstaff/Documents/workspace/employee-maestro/venv_Django_4.2.8/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
          return hook(config_settings)
                 ^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/t8/xbjqyrf55xjdz24_l_dxf_yx93nf6z/T/pip-build-env-n0pd0eb7/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/t8/xbjqyrf55xjdz24_l_dxf_yx93nf6z/T/pip-build-env-n0pd0eb7/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
          self.run_setup()
        File "/private/var/folders/t8/xbjqyrf55xjdz24_l_dxf_yx93nf6z/T/pip-build-env-n0pd0eb7/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 311, in run_setup
          exec(code, locals())
        File "<string>", line 155, in <module>
        File "<string>", line 49, in get_config_posix
        File "<string>", line 28, in find_package_name
      Exception: Can not find valid pkg-config name.
      Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

So I’m confused… I wasn’t using mysql-connector-python originally, yes?

That was just a suggestion to see if we could get around the problem?

I would prefer to be able to use what always worked for Django 3.2 (the same Setting for Engine) if possible.

You were : mysql.connector.django comes from mysql-connector-python. It is not the official mysql backend for django

I see. I inherited this project and am an old Java guy - so I don’ t know this stuff well.

What IS the official Django backend for mysql and how can I get it?

Is THIS the official thing?

venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/mysql/base.py? Because that is the one I identified might have the right thing (mysql_server_data) in it.

If so, how would I reference it in the ENGINE setting?

django.db.backends.mysql ?

Oh, that’s what you gave me, sorry.