2012-11-07 8 views
6

Ich erstelle eine Datenbank in mysql und benutze webpy um meinen Webserver zu erstellen.Warum Chinesisch verstümmelt, wenn Webpy verwenden, aber es ist normal, wenn MySQLdb verwenden?

Aber es ist so komisch für chinesische Zeichen zwischen den Webpy und MySQLdb Verhalten, wenn Sie sie für den Zugriff auf die Datenbank verwenden.

Unten ist mein Problem:

Mein Tisch t_test (utf8 databse):

id  name 
1  测试 

die UTF-8-Code für "测试" ist: \ XE6 \ XB5 \ X8b \ xe8 \ XAF \ x95

wenn MySQLdb mit "wählen sie" wie dies zu tun:

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

das Ergebnis ist normal, er druckt:

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

Aber wenn ich webpy tun die gleichen Dinge verwenden:

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") 

Chinese garble aufgetreten, das Druckergebnis:

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

Ich weiß webpy Datenbank auf MySQLdb auch abhängig ist, aber es ist so anders für diese zwei Wege. Warum?

BTW, aus dem oben genannten Grund, kann ich einfach MySQLdb direkt verwenden, um mein chinesisches Zeichen zu lösen, das Problem, aber es verliert den Clumnum-Namen in der Tabelle - Es ist so ungehörig. Ich möchte wissen, wie ich es mit Webpy lösen kann?

+2

In der Tat - die Zeichenfolge, die Sie abrufen, scheint nur Müll zu sein. Vielleicht sind die Daten in der Datenbank nicht in utf-8 kodiert? Wie wurde es dort aufgenommen? – jsbueno

+0

Ich bin mir sicher, dass die Daten in meiner Datenbank auch utf-8 sind. Ich benutze Navicat, um meine MySQL-Tabelle zu überprüfen, und der Hex-Code für "测试" ist: E6B5 8BE8 AF95. Und Sie können UtraEdit auch verwenden, um dies zu überprüfen. @jsbueno – eason

+0

Nicht sicher, ob relevant, aber das ist, was ich bekomme, wenn ich die verstümmelte Zeichenfolge drucke: http://codepad.org/o3DgYhxr, æμ <è¯ • anstelle von 忙碌 鈥 姑  €. Wo druckst du deine Schnur an? –

Antwort

1

In der Tat passiert etwas sehr falsch - wie Sie auf Ihrem Kommentar, der Unicode repr. Bytes für "测试" sind E6B5 8BE8 AF95 - , die hier auf meinem utf-8-Terminal funktioniert:

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

an den Bytes auf "Kommentar" Unicode-Objekt Aber schauen Sie:

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

Bedeutung Teil Ihre Inhalte sind die utf-8 Bytes für den Kommentar (die Zeichen als „\ xyy“ dargestellt und ein Teil als Unicode codiert ist, Punkte (die mit \ uYYYY vertreten Chares) - dieser schweren Müll zeigt

MySQL hat. etwas Katze chs zum richtigen Decodieren (utf-8 oder anders) codierten Text darin - von denen einer einen richtigen "charset" -Parameter an die Verbindung weiterleitet. Aber Sie haben das bereits getan -

Ein Versuch, den Sie tun können, ist, die Verbindung die Option use_unicode=False - zu übergeben und die utf-8 Zeichenfolgen in Ihrem eigenen Code zu entschlüsseln.

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

Überprüfen Sie die Optionen für diese und andere Parameter verbinden können Sie versuchen:

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

Unabhängig davon bekommen es oben richtig, mit den Hinweisen zu arbeiten, ich habe eine Lösung für Sie - Es sieht aus wie die Unicode-Zeichen (nicht die utf-8 rohen Bytes in den Unicode-Objekten) in Ihrer codierten Zeichenfolge sind in einer dieser Codierungen codiert: ("cp1258", "cp1252", "palmos", " cp1254 ")

Von diesen ist cp1252 fast das gleiche wie "latin1" - das ist der Standard-Zeichensatz MySQL verwendet , wenn es nicht das "charset" Argument in der Verbindung bekommt. Aber es ist nicht nur eine Frage von Web2py nicht an die Datenbank übergeben, wie Sie Mangled Chars bekommen, nicht nur die falsche Codierung - es ist, als ob Web2py Codierung und Dekodierung der Zeichenfolge hin und her, und ignorieren Codierungsfehler

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

so platzieren Sie diese Zeile könnte jetzt für Sie arbeiten,:

aus all diesen Kodierungen ich könnte Ihre ursprüngliche "测试" string, als utf-8-Byte-String, zu tun, zum Beispiel abrufen aber raten mit Unicode ist nie gut - die proepr Sache ist es, einzugrenzen, was web2py macht, um Ihnen diese semi-decodierten utf-8 Saiten auf dem ersten Platz und lass es dort stehen bleiben.

Update

Ich habe hier- das ist, was geschieht - die richtige utf-8 '\xe6\xb5\x8b\xe8\xaf\x95' String aus dem mysql gelesen wird, und es Ihnen, (im use_unicode = True Fall) 0 liefern vor - Diese Bytes werden dekodiert, als ob sie "cp1252" wären - dies ergibt den unkorrekten u'\xe6\xb5\u2039\xe8\xaf\u2022' Unicode. Es ist wahrscheinlich ein web2py Fehler, wie es, Ihren Parameter "charset = utf8" nicht an die tatsächliche Verbindung weitergibt. Wenn Sie "use_unicode = False" setzen, anstatt Ihnen die rohen Bytes zu geben, wählt es scheinbar den inkorrekten Unicode, ein Dencode mit "utf-8" - dies ergibt die '\xc3\xa6\xc2\xb5\xe2\x80\xb9\xc3\xa8\xc2\xaf\xe2\x80\xa2' Sequenz, die Sie unten kommentiert haben (was noch inkorrekter ist) .

alles in allem, die Abhilfe, die ich oben erwähnt, den einzigen Weg scheint, ist, die falsche Unicode gegeben, tut u'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore") -Das die ursprüngliche, richtigen Zeichenfolge abrufen - das heißt, kurz eine andere Sache zu tun up set-to die Datenbankverbindung (oder vielleicht web2py oder mySQL-Treiber aktualisieren, wenn möglich)

** Update 2 ** I futrher den Code in web2py dal.py Datei überprüft sich selbst - es versucht, die Verbindung als utf-8 standardmäßig Setup - aber es sieht so aus, als würde es sowohl MySQLdb als auch pymysql-Treiber versuchen - wenn Sie beide installiert haben, versuchen Sie, pymysql zu deinstallieren, und lassen Sie nur MySQLdb übrig.

+0

Vielen Dank für Ihre detaillierte Analyse! Da es nach den 2 Schritten, die Sie gegeben haben, nicht funktionieren kann, ist es immer noch lehrreich. Wenn ich die Verbindung mit "use_unicode = False" einstelle, bekomme ich einen Rep (comment) wie: \ xc3 \ xa6 \ xc2 \ xb5 \ xe2 \ x80 \ xb9 \ xc3 \ xa8 \ xc2 \ xaf \ xe2 \ x80 \ xa2, das ist es NICHT utf8 kodieren. Dann codiere ich es mit cp1252 (ignore), aber es ist noch nicht erfolgreich. BTW: In meiner ursprünglichen Frage, was das "STRANGE" ich meinte, ist genau Semi utf8 und Semi Unicode, wenn Sie Webpy verwenden, wie Sie jemals zuvor gesagt haben. Also, ich denke es ist vielleicht Webpys Bug. – eason

+0

Wenn man versucht, die obige Sequenz so zu dekodieren, als ob sie in utf-8 wäre, gelangt man zu dem, was man vorher bekommen hat: 'u 'xe6 \ xb5 \ u2039 \ xe8 \ xaf \ u2022''-jetzt wissen wir zumindest Wie ist Web2py dorthin gekommen? – jsbueno