web-dev-qa-db-ja.com

Django MySQL 'utf8'は現在、文字セットUTF8MB3のエイリアスであり、UTF8MB4に置き換えられます

私はDjango 2.0.4、MySQL 8.0.11、mysqlclient-1.3.12およびMac Sierra上のPython 3.6.5を使用しています。以下を受け取ります警告:

/lib/python3.6/site-packages/Django/db/backends/mysql/base.py:71:警告:(3719、「 'utf8'は現在、文字セットUTF8MB3のエイリアスであり、UTF8MB4に置き換えられます将来のリリースでは、明確にするためにUTF8MB4の使用を検討してください。 ")

私はそれが単なる警告であることを知っていますが、それでも、それを見ることは好きではなく、その解決策を模索しています。 UTF8照合UTF8-binとUTF8MB4照合UTF8MB4-binからのさまざまなオプションを使用してスキーマを削除および再作成するなど、いくつかのことを試しましたが、何も機能しないようです。この警告はMySQL/base.pyから送信されますが、MySQLが反対している「utf8」を使用して誰が呼び出しているのかわかりません。

誰かアイデアはありますか?

追加情報

私は以下の回答の後でこれについて少し考えるようになり、これまでのところ、authコマンドの初期セットアップのように見えるものの移行コマンド中にのみこの警告を受け取っていることに気付きました。 sqlmigrateコマンドを使用してすべてのsqlを確認しましたが、utf8についての言及が見られなかったため、なぜそれが起こっているのかわかりません。

(CL)Mac-mini:mysite Lehrian $ python manage.py migrate実行する操作:すべての移行を適用:admin、auth、contenttypes、polls、sessions running migrations:Applying 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を適用しています... 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を適用しています... OK/Users/Lehrian/Documents/Davelopment/CL/-packages/Django/db/backends/mysql/base.py:71:警告:(3719、「 'utf8'は現在、文字セットUTF8MB3のエイリアスであり、将来のリリースでUTF8MB4に置き換えられる予定です。使用を検討してください。 unamになるためのUTF8MB4 biguous。 ")return 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セッションを適用しています。 0001_initial ... OK(CL)Mac-mini:mysite Lehrian $

テストの実行時にも取得しますが、テストは独自のデータベースを作成し(これも文字セットutf8mb4を使用し、test_pollsデータベースを保持して確認しました)、上記と同じ移行を実行するため、これは上記と同じエラーであると結論しました。

4
Lehrian

UTF-8は、MySQL以外の世界で任意のバイト数のUnicodeエンコーディングを呼び出すものです。

utf8(ダッシュなし)はCHARACTER SET MySQLで。 (現在)3バイト文字に制限されているため、一部の中国語および絵文字は含まれていません。

utf8mb4 それは CHARACTER SET 4バイト文字も処理するMySQL内。

Unicode規格では5バイト文字が許可されていますが、近い将来はありません。

文字セットを考慮しないutf16またはutf32(UTF-16またはUTF-32)。

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

Utf8文字セットは現在utf8mb3のエイリアスですが、その時点でutf8mb4への参照になります。 utf8の意味のあいまいさを避けるために、utf8の代わりに文字セット参照に明示的にutf8mb4を指定することを検討してください。

Utf8mb3とutf8mb4の違いを適切に処理するMySQL 8.0(バージョン5.5と5.6にはいくつかの厄介な非互換性がありました)を使用しているため、警告はそれほど大きな問題ではないと思います。

MySQL 8.0のデフォルトはutf8mb4と5.7よりも新しい照合順序。したがって、最初に8.0で作成されたデータベースは、古いバージョンよりも良いはずです。

(すべてのMySQLユーザーに)utf8mb4。これは、近い将来に「最善」に機能するはずです。そうすることで、utf8意味から変更utf8mb3からutf8mb4

4
Rick James

同じ問題があり、列がutf8mb4に設定されている場合でも、特定の絵文字などを保存できませんでした。結局のところ、Djangoはデータベースに接続するときに同じ文字セットを使用していませんでした。これを解決するには、Django OPTIONSに新しいDATABASESエントリを指定します設定、使用する文字セットを指定:

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

最近、まったく同じ問題に遭遇しました。 Djangoにバグリクエストを送りましたが、Djangoはバグとして受け入れません。

MySQL 8は、デフォルトの文字セットとしてUTF8MB3からUTF8MB4に切り替えました。 8.0.11 以降、以前のバージョンで作成されたテーブルにアクセスすると、UTF8MB4に切り替えるように促す警告が返されます。

Inspectdbを実行すると、INFORMATION_SCHEMAテーブルはまだUTF8MB3にあるため、Djangoに警告が返されます。これはDjangoは現在無視できません)。

Djangoバグチケット: https://code.djangoproject.com/ticket/29678 でこのエラーを回避する方法の完全に機能した例があります

堅牢なDjangoアプリケーションのバックエンドとしてMySQL 8.0.12を完全に使用できたので、この問題を乗り越えたら大丈夫でしょう。

私が追加した別の回答からこのテキストをコピーしました here 、それが悪いエチケットなら謝罪

1
Ciaran O'S

確かに私が遅れたとしても、他の誰かがこれで行き詰まった場合に備えて、ここに私のために働いたものがあります。


InnoDBテーブルのインデックスは、utf8では255文字を超えることはできませんが、utf8mb4では191文字のみです。これは、DjangoがCharField(max_length = 255)に対して作成するデフォルトのインデックスが長すぎることを意味します。

ここで255に設定されている場合、VARCHARの長さを191未満に更新する必要があります。

また、charsetフィールドを特に「utf8mb4」に設定します

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

これは、データベースがタイプ(UTF8)を使用していることを示しています。これは将来変更される予定です。

したがって、テーブル設定を変更して、正確なタイプを指定します。

[簡単な理由:mysqlは文字ごとに3バイトのエンコードされたUTF-8(UTF8MB3)を予約するようになりましたが、UTF8MB4を使用して強制的に4バイト(まだUTF-8でエンコードされている)を予約することができます。 Unicode文字は4バイトを必要とする可能性があることを考慮して(UTF-8(およびBTWはUTF-16およびUTF-32でも))、 'utf-8'の将来のデフォルトはUTF8MB4になります。変更と警告です。

照合は、等価性の比較と列の順序付けに使用されますが、文字セットではありません。それが最も目立つように表示されるので、人々は(そして答えは)しばしばそれを混乱させます。 (OTOHは、文字セットと互換性のある照合を使用する必要があります)。

この回答では、文字セットと照合順序を変更する方法について説明します。

MySQLデータベースの文字セット全体と照合順序をUTF-8に変換する方法

0