sql >> データベース >  >> RDS >> Mysql

mysql-python照合の問題:Unicodeデータ型を強制する方法は?

    問題はかなり厄介であることが判明しました。つまり、MySQL文字列データ型 追加のBINARYフラグを使用してMySQLのインターフェースで単一のデータ型にマップします。

    したがって、MySQLのVARCHARVARBINARY 、および文字列リテラルは同じMySQLdb.constants.FIELD_TYPE.VAR_STRINGにマップされます 列タイプの定義を入力しますが、追加のMySQLdb.constants.FLAG.BINARYがあります タイプがVARBINARYの場合のフラグ または*_binと照合された文字列 照合。

    MySQLdb.constants.FIELD_TYPE.VARCHARがありますが タイプ、それがいつ使用されるかを見つけることができませんでした。私が言ったように、MySQL VARCHAR 列はFIELD_TYPE.VAR_STRINGにマップされます 。

    アプリケーションが真のバイナリ文字列を使用する場合(たとえば、画像を保存し、テキストと同じ接続でフェッチする場合)、すべてのバイナリ文字列をUnicodeにデコードすることを前提としているため、ソリューションはかなり脆弱になります。しかし、それは機能します。

    公式のドキュメント として 状態:

    実際には、お尻の本当の痛みは、独自のコンバーター辞書を作成するプロセスかもしれません。ただし、デフォルトのものはMySQLdb.converters.conversionsからインポートできます。 パッチを適用するか、接続のインスタンスにパッチを適用します。秘訣は、FLAG.BINARY用の特別なコンバーターを削除することです。 すべての場合にフラグを立ててデコーダーを追加します。 charsetを明示的に指定した場合 MySQLdb.connectのパラメーター 、use_unicode=1を強制します パラメータ。デコーダを追加しますが、自分で行うこともできます:

    >>> con = MySQLdb.connect(**params)
    >>> con.converter[FIELD_TYPE.VAR_STRING]
    [(128, <type 'str'>), (None, <function string_decoder at 0x01FFA130>)]
    >>> con.converter[FIELD_TYPE.VAR_STRING] = [(None, con.string_decoder)]
    >>> c = con.cursor()
    >>> c.execute("SELECT %s COLLATE utf8_bin", u'м')
    1L
    >>> c.fetchone()
    (u'\u043c',)
    

    FIELD_TYPE.STRINGに対しても同じハックを行う必要があるかもしれません。 必要に応じて。

    別の解決策は、明示的なuse_unicode=0を渡すことです。 MySQLdb.connectへ コード内ですべてのデコードを行いますが、私はしません。

    願わくば、これが誰かに役立つかもしれません。



    1. OracleDatabaseでのPL/SQL例外処理の概要

    2. PHPでセッション配列をループする方法

    3. Python MySQL ReferenceError:弱く参照されているオブジェクトはもう存在しません

    4. コマンドラインからデータベースをエクスポートするにはどうすればよいですか?