問題はかなり厄介であることが判明しました。つまり、MySQL文字列データ型 追加のBINARYフラグを使用してMySQLのインターフェースで単一のデータ型にマップします。
したがって、MySQLのVARCHAR 、VARBINARY 、および文字列リテラルは同じ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へ コード内ですべてのデコードを行いますが、私はしません。
願わくば、これが誰かに役立つかもしれません。