Django MySQL'utf8'目前是字符集UTF8MB3的别名,它将被UTF8MB4取代

时间:2018-04-25 22:27:11

标签: mysql django utf-8 utf8mb4

我在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'进行调用。

有人有什么想法吗?

附加信息

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

  

(CL)Mac-mini:mysite Lehrian $ python manage.py将操作迁移到   执行:应用所有迁移:admin,auth,contenttypes,民意调查,   会话运行迁移:应用contenttypes.0001_initial ...   确定应用auth.0001_initial ...确定应用admin.0001_initial ...   确定应用admin.0002_logentry_remove_auto_add ...确定应用   contenttypes.0002_remove_content_type_name ...确定申请   auth.0002_alter_permission_name_max_length ...确定申请   auth.0003_alter_user_email_max_length ...确定申请   auth.0004_alter_user_username_opts ...确定申请   auth.0005_alter_user_last_login_null ...确定申请   auth.0006_require_contenttypes_0002 ...确定申请   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 ...确定申请   auth.0009_alter_user_last_name_max_length ...确定申请   polls.0001_initial ...确定应用polls.0002_auto_20180425_1458 ...   确定应用sessions.0001_initial ... OK(CL)Mac-mini:mysite   Lehrian $

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

5 个答案:

答案 0 :(得分:3)

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时可能产生的混淆。

答案 1 :(得分:0)

它告诉您数据库使用的类型(UTF8)将来会更改。

因此,请更改表格设置,以便指定确切的类型。

[原因很简单:mysql现在为每个字符保留3个字节编码的UTF-8(UTF8MB3),但你可以使用UTF8MB4强制它保留4个字节(仍以UTF-8编码)。考虑到Unicode字符可能需要4个字节(UTF-8 [以及BTW也采用UTF-16和UTF-32]),未来默认为' utf-8'将是UTF8MB4。所以改变和警告。

排序规则用于比较相等性和排序列,但它不是字符集。人们(以及其他答案)经常会混淆它,因为它最显着。 (OTOH你应该使用与你的字符集兼容的排序规则)。

这个答案解释了如何更改字符集和整理:

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

不确定我是否迟到,但是如果其他人陷入困境,这对我很有用。


使用utf8,InnoDB表中的索引不能超过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
    }
  }
}

答案 4 :(得分:0)

我最近遇到了完全相同的问题。 我向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中复制了此文本,如果这是不好的礼节,则表示歉意