2

重複の可能性:
UTF-8 で 3 バイト以上かかる Unicode 文字をフィルター処理 (または置換) する方法は?

バックグラウンド:

MySQL 5.1 で Django を使用していますが、Web アプリケーション全体で致命的なエラーを引き起こす 4 バイトの UTF-8 文字に問題があります。

スクリプトを使用して、データベース内のすべてのテーブルと列を UTF-8 に変換しました。これにより、ほとんどの Unicode の問題が修正されましたが、4 バイトの Unicode 文字にはまだ問題があります。他の場所で説明したように、MySQL 5.1 は長さが 3 バイトを超える UTF-8 文字をサポートしていません。

Django Web サイトの ModelForm に 4 バイトの Unicode 文字 (例: ) を入力すると、フォームが検証され、次のような例外が発生します。

Incorrect string value: '\xF0\x9F\x80\x90' for column 'first_name' at row 1

私の質問:

MySQL 5.1 データベースを使用する Django Web アプリケーションで 4 バイトの UTF-8 文字が原因で発生する致命的なエラーを回避する合理的な方法は何ですか?

私は考えました:

  1. 特定のエラー メッセージを回避するために、MySQL の警告を選択的に無効にする (まだ可能かどうかは不明)
  2. request.POST QueryDictを調べて無効な UTF8 文字をすべて置換/削除するミドルウェアを作成する
  3. DjangoまたはMySQLdbのSQLクエリを出力するメカニズムにフック/変更/モンキーパッチを適用して、クエリが実行される前にすべての無効なUTF-8文字を置換/削除します

無効な文字を置き換えるミドルウェアの例 (この SO questionに触発された):

import re

class MySQLUnicodeFixingMiddleware(object):

    INVALID_UTF8_RE = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)

    def process_request(self, request):
        """Replace 4-byte unicode characters by REPLACEMENT CHARACTER"""
        request.POST = request.POST.copy()
        for key, values in request.POST.iterlists():
            request.POST.setlist(key,
                [self.INVALID_UTF8_RE.sub(u'\uFFFD', v) for v in values])
4

1 に答える 1

1

mysql をアップグレードするオプションはありますか? その場合は、エンコーディングを utf8mb4 にアップグレードして設定できます。

オプションがないと仮定すると、次のオプションが表示されます。

1) Java スクリプト / フロントエンド検証を追加して、1、2、または 3 バイトの Unicode 文字以外の入力を防止します。

2)モデルのクリーンアップ関数を使用して、4バイトのUnicode文字のデータを削除することを補足します(オプション2または3になります)

同時に、ユーザーが実際に 4 バイト文字を使用しているようにも見えます。アプリケーションでそれらを使用するビジネス ケースがある場合は、その権限にアクセスしてアップグレードを要求できます。

于 2013-01-17T11:09:45.310 に答える