【问题标题】:Django MySQL 'utf8' is currently an alias for the character set UTF8MB3, which will be replaced by UTF8MB4Django MySQL 'utf8' 目前是字符集 UTF8MB3 的别名,将被 UTF8MB4 替换
【发布时间】:2018-04-25 22:27:10
【问题描述】:

我在 Mac Sierra 上使用 Django 2.0.4、MySQL 8.0.11、mysqlclient-1.3.12 和 Python 3.6.5。我收到以下警告:

/lib/python3.6/site-packages/django/db/backends/mysql/base.py:71: 警告: (3719, "'utf8' 当前是字符集 UTF8MB3 的别名,它将是在未来的版本中被 UTF8MB4 取代。请考虑使用 UTF8MB4 以明确。")

我知道这只是一个警告,但我仍然不喜欢看到它并一直在寻找解决方案。我尝试了很多方法,包括使用 UTF8 Collat​​ion UTF8-bin 和 UTF8MB4 Collat​​ion UTF8MB4-bin 中的各种选项删除和重新创建我的 Schema,但似乎没有任何效果。此警告来自 MySQL/base.py,但我不知道谁在使用 MySQL 反对的 'utf8' 进行调用。

有人有什么想法吗?

附加信息

在得到下面的答案后,我开始考虑这个问题,并意识到到目前为止我只在 migrate 命令期间收到此警告,这似乎是 auth 应用程序的初始设置。我用 sqlmigrate 命令查看了所有的 sql,没有看到任何提到 utf8,所以我仍然不知道为什么会发生这种情况

(CL) Mac-mini:mysite Lehrian$ python manage.py migrate 操作到 perform:应用所有迁移:admin、auth、contenttypes、polls、 会话运行迁移:应用 contenttypes.0001_initial... OK 正在应用 auth.0001_initial... OK 正在应用 admin.0001_initial... OK 正在应用 admin.0002_logentry_remove_auto_add... OK 正在应用 contenttypes.0002_remove_content_type_name... OK 正在申请 auth.0002_alter_permission_name_max_length... OK 正在申请 auth.0003_alter_user_email_max_length... OK 申请中 auth.0004_alter_user_username_opts... OK 申请中 auth.0005_alter_user_last_login_null... OK 申请中 auth.0006_require_contenttypes_0002... OK 申请中 auth.0007_alter_validators_add_error_messages... 好的 /Users/Lehrian/Documents/Davelopment/CL/lib/python3.6/site-packages/django/db/backends/mysql/base.py:71: 警告: (3719, "'utf8' 当前是字符集的别名 UTF8MB3,在未来的版本中将被 UTF8MB4 取代。请 考虑使用 UTF8MB4 以便明确。”)返回 self.cursor.execute(query, args) 应用 auth.0008_alter_user_username_max_length... OK 申请中 auth.0009_alter_user_last_name_max_length... OK 申请中 polls.0001_initial... OK 正在应用 polls.0002_auto_20180425_1458... OK 正在应用 session.0001_initial... OK (CL) Mac-mini:mysite 莱里安$

我在运行测试时也得到了它,但我得出结论这与上面的错误相同,因为测试创建了它自己的数据库(也使用字符集 utf8mb4,我保留了 test_polls 数据库并查看了它)并且它运行相同的迁移如上。

【问题讨论】:

  • 商标大写;语法;布局。

标签: mysql django utf-8 utf8mb4


【解决方案1】:

UTF-8 是 MySQL 以外的世界所称的任意字节数的 Unicode 编码。

utf8(没有破折号)是 MySQL 中的 CHARACTER SET。它(当前)限制为 3 字节字符,因此不包括一些中文和表情符号字符。

utf8mb4 是 MySQL 中的 CHARACTER SET,也可以处理 4 字节字符。

虽然 Unicode 标准允许 5 字节字符,但在不久的将来不会有。

不要考虑字符集 utf16utf32(UTF-16 或 UTF-32)。

https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html

utf8 字符集目前是 utf8mb3 的别名,但届时将成为对 utf8mb4 的引用。为避免对 utf8 的含义产生歧义,请考虑为字符集引用显式指定 utf8mb4 而不是 utf8。

由于您使用的是 MySQL 8.0,它可以很好地处理 utf8mb3 和 utf8mb4 之间的差异(版本 5.5 和 5.6 存在一些令人讨厌的不兼容问题),我认为警告并不是什么大问题。

MySQL 8.0 默认为 utf8mb4 和比 5.7 更新的排序规则。因此,最初在 8.0 中创建的数据库应该比旧版本更好。

我建议(对所有 MySQL 用户)使用utf8mb4。在可预见的未来,这应该是“最好的”。这样做可以避免 utf8 从含义 utf8mb3 变为 utf8mb4 时可能出现的混淆。

【讨论】:

    【解决方案2】:

    我最近遇到了完全相同的问题。 我向 Django 提出了一个错误请求,但 Django 不接受它作为他们的错误。

    MySQL 8 已从 UTF8MB3 切换到 UTF8MB4 作为默认字符集。从8.0.11 开始,如果您访问使用先前版本创建的表,则会返回警告,鼓励您切换到 UTF8MB4。

    当您运行 inspectdb 时,INFORMATION_SCHEMA 表仍为 UTF8MB3,因此您会收到返回给 Django 的警告,Django 目前无法忽略该警告。

    我有一个完整的示例,说明如何在 Django 错误票上解决此错误: https://code.djangoproject.com/ticket/29678

    我已经能够完全使用 MySQL 8.0.12 作为强大的 Django 应用程序的后端 所以一旦你解决了这个问题,你应该会没事的。

    我从另一个答案中复制了这段文字,我添加了here,如果这是不礼貌的行为,我深表歉意

    【讨论】:

      【解决方案3】:

      它告诉您您的数据库使用了一种类型 (UTF8),它将在未来发生变化。

      所以更改表格设置,以便您指定确切的类型。

      [简而言之:mysql现在为每个字符保留3个字节编码的UTF-8(UTF8MB3),但你可以强制它保留4个字节(仍然以UTF-8编码),使用UTF8MB4。考虑到 Unicode 字符可能需要 4 个字节(在 UTF-8 中[顺便说一句,在 UTF-16 和 UTF-32 中也是如此]),“utf-8”的未来默认值将是 UTF8MB4。所以变化和警告。

      排序规则用于比较相等性和排序列,但它不是字符集。人们(因此回答)经常混淆它,因为它显示得最突出。 (OTOH,您应该使用与您的字符集兼容的排序规则)。

      这个答案解释了如何更改字符集和排序规则:

      How to convert an entire MySQL database characterset and collation to UTF-8?

      【讨论】:

      • 我的研究向我指出了这个结论,但是,我删除了架构并使用字符集 utf8mb4 重新创建它,但我仍然收到相同的警告。我只是仔细检查了 MySQL 中的模式详细信息,它绝对是 utf8mb4。所以我仍然不知道为什么我会收到这个警告。我只能假设 Django 正在做某事导致它,但我不知道是什么。
      • 警告似乎源自 mysql。检查您的客户端 mysql 以及 python mysql 模块是否已更新。
      • 在 mysql 8 和 node js 上也能正常工作! :)
      【解决方案4】:

      我也遇到过同样的问题,即使我的列设置为utf8mb4,它仍然无法保存某些表情符号字符等内容。事实证明,Django 在连接数据库时没有使用相同的字符集。为了解决这个问题,你可以在 Django DATABASES 设置中指定一个新的 OPTIONS 条目,告诉它使用哪个字符集:

      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'USER': 'xxxxx',
              'PASSWORD': 'xxxxx',
              'HOST': 'localhost',
              'OPTIONS': {
                  'charset': 'utf8mb4',  # <--- Use this
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        不确定我是否迟到了,但万一其他人对此感到困惑,这里有一些对我有用的东西。


        InnoDB 表中的索引在 utf8 中不能超过 255 个字符,但在 utf8mb4 中只能超过 191 个字符。这意味着 Django 为 CharField(max_length=255) 创建的默认索引太长了。

        如果现在将 VARCHAR 长度设置为 255,则需要将其更新为小于 191。

        还将字符集字段专门设置为“utf8mb4”

        DATABASES = {
          'default': {
          'USER': 'xxxxx',
          'PASSWORD': 'xxxxx',
          'HOST': 'localhost',
          'OPTIONS': {
              'charset': 'utf8mb4',  # The characterset you need
            }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-16
          • 1970-01-01
          • 2016-05-31
          • 2013-08-18
          • 1970-01-01
          • 1970-01-01
          • 2021-06-30
          • 2021-11-22
          相关资源
          最近更新 更多