6

mysql でデータベースを作成し、webpy を使用して Web サーバーを構築します。

しかし、webpy と MySQLdb をそれぞれデータベースにアクセスするために使用する場合、これらの動作の間の漢字は非常に奇妙です。

以下は私の問題です:

私のテーブル t_test (utf8 データベース):

id     name
1      测试

「测试」の utf8 コードは次のとおりです: \xe6\xb5\x8b\xe8\xaf\x95

MySQLdb を使用して次のように「選択」を行う場合:

    c=conn.cursor()
    c.execute("SELECT * FROM t_test")
    items = c.fetchall()
    c.close()
    print "items=%s, name=%s"%(eval_items, eval_items[1])

結果は正常です。次のように表示されます。

    items=(127L, '\xe6\xb5\x8b\xe8\xaf\x95'), name=测试

しかし、webpy を使用するときは、同じことを行います。

    db = web.database(dbn='mysql', host="127.0.0.1", 
             user='test', pw='test', db='db_test', charset="utf8")
    eval_items=db.select('t_test')
    comment=eval_items[0].name
    print "comment code=%s"%repr(comment)
    print "comment=%s"%comment.encode("utf8")

中国語の文字化けが発生しました。印刷結果は次のとおりです。

    comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022'
    comment=忙碌鈥姑€

webpy のデータベースも MySQLdb に依存していることは知っていますが、この 2 つの方法では大きく異なります。なんで?

ところで、上記の理由により、MySQLdb を直接使用して漢字の文字化けの問題を解決できますが、表の列名が失われます。どうすればwebpyで解決できるか知りたいですか?

4

1 に答える 1

1

確かに、何か非常に間違ったことが起こっています - あなたがコメントで言ったように、ユニコード表現。「测试」のバイトは E6B5 8BE8 AF95 です - これは私の utf-8 端末で動作します:

>>> d
'\xe6\xb5\x8b\xe8\xaf\x95'
>>> print d
测试

しかし、「コメント」ユニコード オブジェクトのバイトを見てください。

comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022'

コンテンツの一部がコメントの utf-8 バイトであることを意味します (文字は "\xYY" として表され、一部は Unicode ポイント ( \uYYYY で表される文字) としてエンコードされます) - これは深刻なゴミを示します。

MySQL には、エンコードされたテキスト (utf-8 またはそれ以外) を適切にデコードするためのキャッチがいくつかあります。そのうちの 1 つは、適切な「charset」パラメーターを接続に渡しています。しかし、あなたはすでにそれをしました -

できることの 1 つは、接続にオプションを渡し、use_unicode=False 独自のコードで utf-8 文字列をデコードすることです。

db = web.database(dbn='mysql', host="127.0.0.1", 
         user='test', pw='test', db='db_test', charset="utf8", use_unicode=False)

接続するためのオプションを確認して、これと他のパラメーターを試すことができます。

http://mysql-python.sourceforge.net/MySQLdb.html

正しく動作するかどうかに関係なく、上記のヒントを使用して回避策を用意しました-エンコードされた文字列のUnicode文字(Unicodeオブジェクトのutf-8 rawバイトではない)は、これらのいずれかでエンコードされているようですエンコーディング: ("cp1258"、"cp1252"、"palmos"、"cp1254")

これらのうち、cp1252 は「latin1」とほぼ同じです。これは、接続で「charset」引数を取得しない場合に MySQL が使用するデフォルトの文字セットです。しかし、間違ったエンコーディングだけでなく、文字が壊れているため、web2pyがデータベースに渡さないという問題だけではありません.web2pyが文字列を前後にエンコードおよびデコードし、エンコーディングエラーを無視しているようです.

これらすべてのエンコーディングから、元の「测试」文字列を utf-8 バイト文字列として取得できます。たとえば、次のようにします。

comment = comment.encode("cp1252", errors="ignore")

したがって、この行を配置するとうまくいくかもしれませんが、Unicode で推測するのは決して良いことではありません - 適切なことは、web2py を作成している原因を絞り込んで、最初にセミデコードされた utf-8 文字列を提供し、それを作成することです。そこで止まれ。

アップデート

ここで確認しました-これが起こっていることです-正しいutf-8'\xe6\xb5\x8b\xe8\xaf\x95'文字列がmysqlから読み取られ、それを配信する前に(use_unicode=Trueの場合)0-これらのバイトは「cp1252」であるかのようにデコードされます" - これにより、正しくないu'\xe6\xb5\u2039\xe8\xaf\u2022'Unicode が生成されます。「charset=utf8」パラメーターを実際の接続に渡さないなど、おそらく web2py エラーです。生のバイトを提供する代わりに「use_unicode = False」を設定すると、明らかに誤ったユニコードが選択され、「utf-8」を使用してデコードされます-これにより、 '\xc3\xa6\xc2\xb5\xe2\x80\xb9\xc3\xa8\xc2\xaf\xe2\x80\xa2'以下にコメントしたシーケンスが得られます(これはさらに間違っています)。

全体として、上記の回避策は、元の正しい文字列を取得する唯一の方法のようですu'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore")。可能であれば、web2py または mysql ドライバーを更新してください)

** 更新 2 ** web2pydal.pyファイル自体のコードをさらにチェックしました - デフォルトで utf-8 として接続をセットアップしようとします - しかし、MySQLdb と pymysql の両方のドライバーを試すようです - 両方がインストールされている場合は、アンインストールしてみてくださいpymysql を削除し、MySQLdb のみを残します。

于 2012-11-07T21:43:12.217 に答える