Type Error running migration

I have recently updated my Django project’s Python version to 3.11 and Django to 4.2.7

I tested vigorously, but did not test migrations.

I just had to add a field to the database and I now get an error when running “migrate agents”.

Note: the error does NOT occur against the sqlLite3 local database, but DOES occur running against my Dev environment which has a real MySQL 8 instance.

Also worthy of note, the following are all at their latest versions according to PiPy…
django-mysql==4.12.0
mysql-connector-python==8.3.0
PyMySQL==1.1.0

Here is the stack trace. I do understand that something is sending “too much” into something else, but am at a loss to explain exactly what and why… Nor how to fix.

Traceback (most recent call last):
  File "/Users/redacted/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13135.95/PyCharm.app/Contents/plugins/python/helpers/pycharm/django_manage.py", line 52, in <module>
    run_command()
  File "/Users/redacted/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13135.95/PyCharm.app/Contents/plugins/python/helpers/pycharm/django_manage.py", line 46, in run_command
    run_module(manage_file, None, '__main__', True)
  File "<frozen runpy>", line 226, in run_module
  File "<frozen runpy>", line 98, in _run_module_code
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/redacted/Documents/workspace/redacted_app_name/manage.py", line 25, in <module>
    main()
  File "/Users/redacted/Documents/workspace/redacted_app_name/manage.py", line 21, in main
    execute_from_command_line(sys.argv)
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 100, in handle
    self.check(databases=[database])
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/management/base.py", line 485, in check
    all_issues = checks.run_checks(
                 ^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/core/checks/database.py", line 13, in check_database_backends
    issues.extend(conn.validation.check(**kwargs))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 9, in check
    issues.extend(self._check_sql_mode(**kwargs))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/venv_Django_4.2.7/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 19, in _check_sql_mode
    % (self.connection.display_name, self.connection.alias),
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/redacted/Documents/workspace/redacted_app_name/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)
                                         ^^^^^^^^^^^^^^^^^^^
TypeError: DatabaseWrapper.display_name() takes 0 positional arguments but 1 was given

Process finished with exit code 1

Any hints gratefully accepted!

If you want to see more (database settings etc) let me know…

It does appear that the issue may be related to the database configuration. Please post your DATABASES configuration. (Feel free to obfuscate the password.)

if RUNNING_LOCALLY:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3')
        }
    }

elif ENV.lower() == 'docker':
    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)
        }
    }

elif RUNNING_BATCH:
    db_credentials = get_secret(f'/{ENV}/batch/employee-maestro/rds')['secret']
    logging.info(f"patching database connection with username: {db_credentials['username']}")

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

else:
    # DATABASES = {
    #     'default': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': os.path.join(BASE_DIR, 'db.sqlite3')
    #     }
    # }
    db_credentials = get_secret(f'/{ENV}/app/employee-maestro/rds')['secret']
    logging.info(f"patching database connection with username: {db_credentials['username']}")

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

We are falling through to the final else here, IF we are not running locally.

I don’t see where

is defined as an appropriate Django connection engine.

The engine itself is listed as 'django.db.backends.mysql'

I had a conversation about this in another thread earlier…

The engine you list is (as I understand it) the “official” django engine.

The one I’m using has been in this project since the beginning and is from a different “provider”

See this question…

https://forum.djangoproject.com/t/database-connection-failing-on-upgrade-to-4-2-7/27054/20

I chose to stick with the original “non official” library because I didn’t want to do the compile by hand suggested by the gentleman who was assisting me…

I would at least try it with the official engine to verify whether the issue is engine-related or not.

Per the discussion on the other thread, that is a lot of work since there is no wheel on pypi for mysqlclient (except for windows), and pip needs to build the wheel from sources,

However I may have no choice. Thank you.

Are there possibly other drivers/libraries I could drop in without this effort?

Aurora or MariaDB for example?

The only “work” involved is ensuring you have all the necessary development packages installed. Pip itself will run the compile steps.

In my case, the distro (Ubuntu) packages the prereq as libmysqlclient-dev. (Which also results in two other packages being involved - libmysqlclient21 and
default-libmysqlclient-dev.)

Once having done that, a pip install of mysqlclient worked fine.

here’s what I understand from the other conversation:

django.db.backends.mysql is the official one (embedded in django) but it requires a mysqldb API driver (see Databases | Django documentation | Django).

mysqlclient is one of this DB API driver. As there is no wheel on pypi for it (except for windows), pip needs to build the wheel from sources, hence the error you encoutered. In order to be able to build it you have to install some devel packages (see documentation at mysqlclient · PyPI )

I use Ubuntu.

I used aptitude to install libmysqlclient-dev, libmysqlclient21 and default-libmysqlclient-dev.

Once I did that, I ran pip install mysqlclient.

Thanks for the library names.

I’ll stare at the docs and see if that helps me get around the need to “build the wheel from sources”

“You” are “building the wheel from sources” when you run that pip command. That’s what I’m trying to explain here. Those commands (basically the ones documented on the pypi page you referenced), is all you need to do.

I see. Thanks for the clarification.

I found this… (I know you don’t like SO, Ken, but this did the trick)

https://stackoverflow.com/questions/77421346/typeerror-databasewrapper-display-name-takes-0-positional-arguments-but-1-was

I changed the Database setting’s OPTIONS to contain this init_command and it works fine again.

'OPTIONS': {
                'connect_timeout': 30,
                'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"
            }