web-dev-qa-db-fra.com

Django MySQL 'utf8' est actuellement un alias pour le jeu de caractères UTF8MB3, qui sera remplacé par UTF8MB4

J'utilise Django 2.0.4, MySQL 8.0.11, mysqlclient-1.3.12 et Python 3.6.5 sur Mac Sierra. Je reçois l'avertissement suivant:

/lib/python3.6/site-packages/Django/db/backends/mysql/base.py:71: Avertissement: (3719, "utf8" est actuellement un alias du jeu de caractères UTF8MB3, qui sera remplacé par UTF8MB4. Veuillez envisager d’utiliser UTF8MB4 afin d’être sans ambiguïté. ")

Je sais que c'est juste un avertissement, mais je n'aime toujours pas le voir et j'ai cherché une solution. J'ai essayé un certain nombre de choses, notamment supprimer et recréer mon schéma avec diverses options de UTF8 Collation UTF8-bin et UTF8MB4 Collation UTF8MB4-bin, mais rien ne semble fonctionner. Cet avertissement provient de MySQL/base.py mais je ne sais pas qui passe l'appel avec 'utf8' auquel MySQL s'oppose. 

Quelqu'un a des idées?

INFORMATION ADDITIONNELLE

J'ai commencé à réfléchir à cela un peu plus après la réponse ci-dessous et je me suis rendu compte que je n'avais jusqu'à présent reçu cet avertissement que lors de la commande migrate au cours de ce qui semblait être la configuration initiale de l'application auth. J'ai regardé tous les SQL avec la commande sqlmigrate et je n'ai vu aucune mention d'utf8, donc je ne sais toujours pas pourquoi cela se produit 

(CL) Mac-mini: mysite Lehrian $ python manage.py migrer Opérations vers Effectuer: Appliquer toutes les migrations: admin, authentification, types de contenu, sondages, Sessions Lancement de migrations: Application de types de contenu.0001_initial. .. OK Application de auth.0001_initial ... OK Application de admin.0001_initial ... OK Application de admin.0002_logentry_remove_auto_add ... OK Application de Contenttypes.0002_remove_content_type_name ... OK Application de Auth.0002_alter_permission_name_max_length ... OK Application de Auth.0003_alter_user_email_max_length ... OK Application de Auth.0004_alter_user_username_opts_opts ... OK Application de Auth.0004_alter_user_username_opts ... OK Application de. . OK Application de Auth.0006_require_contenttypes_0002 ... OK Application de Auth.0007_alter_validators_add_error_messages ... OK /Users/Lehrian/Documents/Davelopment/CL/lib/python3.6/ sites-packages/Django/db/backends/mysql/base.py: 71: Attention: (3719, "'utf8' est actuellement un alias pour le jeu de caractères UTF8MB3, qui sera remplacé par UTF8MB4 dans une version ultérieure. Veuillez Envisager d’utiliser UTF8MB4 afin d’être univoque. ") Renvoyer Self.cursor.execute (requête, arguments) Application de Auth.0008_alter_user_username_max_length ... OK Application de. .] auth.0009_alter_user_last_name_max_length ... OK Application polls.0001_initial ... OK Application de polls.0002_auto_20180425_1458 ... OK Application de sessions.0001_initial ... OK (CL) Mac-mini: mysite Lehrian $

Je l’obtiens également lors de l’exécution de tests, mais j’en conclus que c’est la même erreur que ci-dessus, car les tests créent leur propre base de données (également avec le jeu de caractères utf8mb4, j’ai préservé la base de données test_polls et je l’ai regardée) et il effectue la même migration que précédemment. 

2
Lehrian

UTF-8 est ce que le monde extérieur à MySQL appelle le codage Unicode pour n’importe quel nombre d’octets.

utf8 (pas de tiret) est un CHARACTER SET dans MySQL. Il est (actuellement) limité aux caractères de 3 octets, par conséquent, n'inclut pas certains caractères chinois et Emoji.

utf8mb4 est le CHARACTER SET dans MySQL qui gère également les caractères de 4 octets.

Bien que la norme Unicode permette l'utilisation de caractères sur 5 octets, il n'y en aura pas dans un avenir proche.

Ne considérez pas les jeux de caractères utf16 ou utf32 (UTF-16 ou UTF-32).

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

Le jeu de caractères utf8 est actuellement un alias pour utf8mb3, mais deviendra à ce stade une référence à utf8mb4. Pour éviter toute ambiguïté sur la signification de utf8, envisagez de spécifier explicitement utf8mb4 pour les références de jeux de caractères au lieu de utf8. 

Étant donné que vous utilisez MySQL 8.0, qui gère bien les différences entre utf8mb3 et utf8mb4 (les versions 5.5 et 5.6 présentaient des incompatibilités gênantes), je considère que l’avertissement n’est pas très grave.

La valeur par défaut de MySQL 8.0 est utf8mb4 et un classement plus récent que celui de 5.7. Ainsi, les bases de données créées initialement dans la version 8.0 devraient être mieux loties que dans les versions antérieures.

Je recommande (à tous les utilisateurs de MySQL) d'utiliser utf8mb4. Cela devrait fonctionner "au mieux" dans un avenir prévisible. Cela évitera la confusion qui pourrait en résulter lorsque utf8 changera de signification utf8mb3 à utf8mb4.

2
Rick James

J'ai eu le même problème, et même lorsque mes colonnes sont définies sur utf8mb4, il ne parvenait toujours pas à enregistrer des éléments tels que certains caractères emoji. Il s'avère que Django n'utilisait pas le même jeu de caractères lors de la connexion à la base de données. Pour résoudre ce problème, vous pouvez spécifier une nouvelle entrée OPTIONS dans le paramètre Django DATABASES, en lui indiquant le jeu de caractères à utiliser:

DATABASES = {
    'default': {
        'ENGINE': 'Django.db.backends.mysql',
        'USER': 'xxxxx',
        'PASSWORD': 'xxxxx',
        'Host': 'localhost',
        'OPTIONS': {
            'charset': 'utf8mb4',  # <--- Use this
        }
    }
}
0
Dan Breen

Pas sûr Si je suis en retard, mais au cas où quelqu'un d'autre resterait coincé avec ça, voici quelque chose qui a fonctionné pour moi.


Les index dans les tables InnoDB ne peuvent pas dépasser 255 caractères avec utf8, mais seulement 191 caractères avec utf8mb4. Cela signifie que les index par défaut créés par Django pour CharField (longueur_max = 255) sont trop longs.

Vous devrez mettre à jour la longueur de VARCHAR sur une valeur inférieure à 191 si elle est définie sur 255 maintenant.

Définissez également le champ charset sur 'utf8mb4' spécifiquement 

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

J'ai rencontré le même problème récemment. J'ai adressé une demande de bogue à Django, mais Django ne l'accepte pas comme bogue.

MySQL 8 est passé de UTF8MB3 à UTF8MB4 en tant que jeu de caractères par défaut. À partir de 8.0.11 si vous accédez à une table créée avec la version précédente, un avertissement vous est renvoyé pour vous encourager à passer à UTF8MB4. 

Lorsque vous exécutez inspectdb, les tables INFORMATION_SCHEMA sont toujours en UTF8MB3. Vous recevez donc l'avertissement renvoyé à Django, que Django ne peut actuellement pas ignorer. 

J'ai un exemple complet de comment contourner cette erreur sur le ticket de bogue Django: https://code.djangoproject.com/ticket/29678

J'ai été en mesure d'utiliser pleinement MySQL 8.0.12 comme back-end pour une application Django robuste . Une fois cette question résolue, tout devrait bien se passer.

J'ai copié ce texte à partir d'une autre réponse que j'ai ajoutée ici , excuses si c'est mauvais 

0
Ciaran O'S

Il vous indique que votre base de données utilise un type (UTF8), qui sera modifié à l'avenir.

Modifiez donc les paramètres de la table afin de spécifier le type exact.

[La raison en bref: mysql réserve maintenant 3 octets codés UTF-8 (UTF8MB3) par caractère, mais vous pouvez le forcer à réserver 4 octets (toujours codés en UTF-8), en utilisant UTF8MB4. Considérant que les caractères Unicode peuvent nécessiter 4 octets (en UTF-8 [et BTW également en UTF-16 et UTF-32]), la valeur par défaut future de 'utf-8' sera UTF8MB4. Donc, le changement et l'avertissement.

La collation est utilisée pour comparer l'égalité et pour ordonner les colonnes, mais ce n'est pas le jeu de caractères. Les gens (et donc leurs réponses) le confondent souvent car il est affiché de manière très visible. (OTOH, vous devez utiliser un classement compatible avec votre jeu de caractères).

Cette réponse explique comment modifier le jeu de caractères et le classement:

Comment convertir un jeu de caractères de base de données MySQL et un classement en UTF-8?

0
Giacomo Catenazzi