【问题标题】:AttribueError with Django and mysql connector pythonAttribueError 与 Django 和 mysql 连接器 python
【发布时间】:2021-07-12 21:30:09
【问题描述】:

我在我的 django 数据库中使用 SQLite,我想在我的 Synology NAS 上使用 MariaDb。

我在 Python 3.9.0+ 和 MariaDB 10.3.24 上使用 Django 3.2

我使用 pip 包 mysql-connector-python==8.0.23 作为 mysql 连接器。

DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django',
        'NAME': 'energyHomeWeb_django',
        'USER': 'energyHomeWeb',
        'PASSWORD': 'password',
        'HOST': '192.168.1.123',
        'PORT': '3307',
        'OPTIONS': {
            'autocommit': True,
        },
    }
}

当我想启动或迁移我的服务器时,我遇到了这个错误:

      Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 950, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 888, in run
    self._target(*self._args, **self._kwargs)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
    self.check_migrations()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/core/management/base.py", line 486, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
    self.build_graph()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/migrations/loader.py", line 220, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
    if self.has_table():
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
    with self.connection.cursor() as cursor:
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/backends/base/base.py", line 202, in connect
    self.init_connection_state()
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/mysql/connector/django/base.py", line 341, in init_connection_state
    if self.features.is_sql_auto_is_null_enabled:
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/django/db/backends/mysql/features.py", line 150, in is_sql_auto_is_null_enabled
    return self.connection.mysql_server_data['sql_auto_is_null']
  File "/home/iomys/.virtualenvs/energyHomeWeb/lib/python3.9/site-packages/mysql/connector/django/base.py", line 290, in __getattr__
    raise AttributeError
AttributeError

我该如何解决这个问题?

PS:我不使用 mysqlclient,因为它不能在我的 virtualenv 上工作,而且我不知道如何让它工作。

【问题讨论】:

    标签: python mysql django mariadb mysql-connector-python


    【解决方案1】:

    引擎不正确

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', 
            'NAME': 'energyHomeWeb_django',
            'USER': 'energyHomeWeb',
            'PASSWORD': 'password',
            'HOST': '192.168.1.123',
            'PORT': '3307',
            'OPTIONS': {
                'autocommit': True,
            },
        }
    }
    

    【讨论】:

    • 我用的不是mysqlclient,而是mysql-connector-python
    【解决方案2】:

    最后,我将我的 Python 版本更改为 Python 3.8,mysqlclient 可以在 python3.8 上正常工作。

    所以我使用了它,它现在可以工作了,但是有了这个配置:

    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'energyHomeWeb_django',
        'USER': 'energyHomeWeb',
        'PASSWORD': 'password',
        'HOST': '192.168.1.123',
        'PORT': '3307',
        'OPTIONS': {
            'autocommit': True,
            },
        }
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的错误。

      pip freeze 的输出

      asgiref==3.3.4
      asttokens==2.0.4
      colorama==0.4.4
      Django==3.2
      dnspython==1.16.0
      executing==0.6.0
      icecream==2.1.0
      mysql-connector-python==8.0.23
      protobuf==3.15.8
      Pygments==2.8.1
      pytz==2021.1
      six==1.15.0
      sqlparse==0.4.1
      

      在浏览了源代码后,我通过对文件venv/lib/python3.8/site-packages/mysql/connector/django/base.py做一点小改动解决了这个问题(假设您使用的是 venv 并将您的虚拟环境命名为 venv)

          def __getattr__(self, attr):
              if attr.startswith("mysql_is"):
                  return False
              raise AttributeError
          
          # copied from venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py
          # and modified to use with self.cursor() as cursor: (see init_connection_state() )
          @cached_property
          def mysql_server_data(self):
              with self.cursor() 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]),
              }
      

      升级到 8.0.24 版本对我来说不是一个选项,因为它会产生另一个错误。

      【讨论】:

      • 感谢您的意见!我尚未测试您的解决方案,因为现在我的配置有效。
      猜你喜欢
      • 2019-06-15
      • 2011-02-18
      • 2018-04-23
      • 1970-01-01
      • 2013-07-24
      • 2014-05-24
      • 1970-01-01
      • 2020-08-16
      • 1970-01-01
      相关资源
      最近更新 更多