2012-11-07 18 views
6

Tworzę bazę danych w mysql i używam webpy do budowy mojego serwera WWW.Dlaczego Chińczycy są zniekształceni podczas korzystania z webpy, ale to normalne, gdy używacie MySQLdb?

Ale to jest tak dziwne dla chińskiego bohatera między zachowaniami webpy i MySQLdb, gdy używa się ich odpowiednio do dostępu do bazy danych.

Poniżej jest mój problem:

Moja tabela t_test (utf8 databse):

id  name 
1  测试 

kod utf8 dla "测试" jest: \ XE6 \ XB5 \ x8b \ xe8 \ XAF \ x95

przy użyciu MySQLdb zrobić "wybierz" tak:

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

wynik jest prawidłowy, to drukuje:

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

Ale gdy używam webpy robić te same rzeczy:

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

chiński garble wystąpił, wynik wydruku jest: baza

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

wiem webpy jest również zależna od MySQLdb, ale jest tak różny dla tych dwóch sposobów. Czemu?

BTW, z powyższego powodu, mogę po prostu użyć MySQLdb bezpośrednio, aby rozwiązać problem z chińską literą, ale traci nazwę kolumny w tabeli - To jest tak bezwstydne. Chcę wiedzieć, jak mogę rozwiązać ten problem za pomocą webpy?

+2

Rzeczywiście - ciąg, który pobierasz, wydaje się być tylko śmieciem. Może dane w bazie danych nie są zakodowane w utf-8? Jak to się tam zapisało? – jsbueno

+0

Jestem pewien, że dane w mojej bazie danych są również utf-8. Używam programu Navicat do sprawdzania mojej tabeli mysql, a kod szesnastkowy dla "测试" to: E6B5 8BE8 AF95. A także, możesz użyć UtraEdit, aby to sprawdzić. @jsbueno – eason

+0

Nie jestem pewien czy jest to istotne, ale to właśnie dostaję, gdy wydrukuję zniekształcony ciąg: http://codepad.org/o3DgYhxr, æμ <è¯ • zamiast 忙碌 鈥 姑  €. Gdzie drukujesz swój ciąg? –

Odpowiedz

1

Rzeczywiście, dzieje się coś bardzo złego - , jak powiedziałeś w swoim komentarzu, replikę unicode. bajty dla "测试" są E6B5 8BE8 AF95 - który działa na moim terminalu UTF-8 tutaj:

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

Ale spójrz na bajty na "komentarz" unicode obiektu:

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

Znaczenie części z treści są UTF-8 bajtów dla komentarzu (te znaki reprezentowane jako "XYY \" i części jest kodowany jako Unicode punkty (the Chares reprezentowane z \ uYYYY) - oznacza to poważne śmieci

MySQL ma. jakiś kot chs do poprawnego dekodowania (utf-8 lub w inny sposób) zakodowanego w nim tekstu: - jeden z nich przekazuje do połączenia odpowiedni parametr "charset" . Ale zrobiłeś to już -

Jedną próbą, którą możesz zrobić, jest przekazanie połączenia opcji use_unicode=False - i dekodowanie ciągów utf-8 we własnym kodzie.

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

Sprawdź opcje podłączyć do tego i innych parametrów można spróbować:

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

Niezależnie od uzyskania go do pracy poprawnie, z podpowiedzi powyżej, mam obejście ty - Wygląda jak znaki Unicode (nie surowe bajty utf-8 w obiektach unicode) w zakodowanym ciągu są kodowane w jednym z następujących kodowań: ("cp1258", "cp1252", "palmos", " cp1254 ")

Spośród nich, cp1252 jest prawie taki sam jak "latin1" - który jest domyślnym zestawem znaków MySQL używa , jeśli nie otrzymuje argumentu "charset" w połączeniu. Ale nie jest to tylko kwestia, czy web2py nie przekazuje go do bazy danych, ponieważ dostajesz zmanipulowane znaki, a nie tylko złe kodowanie - to tak, jakby web2py kodował i dekodować twój ciąg w tył i w przód, ignorując błędy kodowania

z tych wszystkich kodowań mogę odzyskać swój pierwotny „测试” ciąg jako UTF-8 bajtowy ciąg, robi, na przykład:

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

więc umieszczenie tej linii może pracować dla ciebie, ale zgadywanie z unicode nigdy nie jest dobre - rzeczą proepr jest zawężenie tego, co robi web2py, aby ci te pół-dekodowane ciągi utf-8 na pierwszym miejsce, i zatrzymaj się tam.

aktualizacja

Sprawdziłem tutaj- to, co się dzieje - prawidłowe UTF-8 '\xe6\xb5\x8b\xe8\xaf\x95' łańcuch jest odczytywany z mysql, a przed dostarczeniem go do ciebie, (w przypadku use_unicode = true) 0 - Bajty te są dekodowane tak, jakby miały "cp1252" - co daje niepoprawny kod Unicode u'\xe6\xb5\u2039\xe8\xaf\u2022'. Jest to prawdopodobnie błąd web2py, np. Nie przekazuje parametru "charset = utf8" do rzeczywistego połączenia. Kiedy ustawisz "use_unicode = False" zamiast podawania surowych bajtów, najwyraźniej wybierzesz niepoprawny kod Unicode, kod dencode użyjesz "utf-8" - to spowoduje, że skomentowałeś poniższą sekwencję (co jest jeszcze bardziej niepoprawne) .

w sumie, obejście wspomniałem powyżej wydaje się, że jedynym sposobem, aby odzyskać pierwotną, poprawny ciąg -to znaczy, ze względu na zły Unicode, wykonaj u'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore") - czyli krótki jakiejś innej rzeczy do set-up połączenie z bazą danych (lub może aktualizować sterowniki Web2py lub MySQL, jeśli to możliwe)

** aktualizacja 2 ** I futrher sprawdził kod w samej Web2py dal.py pliku - próbuje skonfigurować połączenia jako UTF-8 domyślnie - ale wygląda na to, że spróbuje obu sterowników MySQLdb i pymysql - jeśli masz oba zainstalowane, spróbuj odinstalować pymysql i pozostaw tylko MySQLdb.

+0

Dziękuję za szczegółową analizę! Ponieważ nie może działać po dwóch podanych krokach, nadal jest pouczający. Kiedy ustawiłem połączenie z "use_unicode = False", dostałem repr (komentarz), jak: \ xc3 \ xa6 \ xc2 \ xb2 \ xe2 \ x80 \ xb9 \ xc3 \ xa8 \ xc2 \ xaf \ xe2 \ x80 \ xa2, to Kodowanie NOT utf8. Następnie koduję to za pomocą cp1252 (ignore), ale jeszcze się nie udało. BTW: W moim pierwotnym pytaniu, co miałam na myśli "STRANGE", to dokładnie semi utf8 i semi unicode, gdy korzystasz z webpy, jak już wcześniej powiedziałeś. Myślę, że to może być błąd webpy. – eason

+0

Jeśli ktoś próbuje zdekodować powyższą sekwencję, tak jak w utf-8, dostaje się do tego, co otrzymujesz wcześniej: 'u '\ xe6 \ xb5 \ u2039 \ xe8 \ xaf \ u2022'' -Teraz przynajmniej wiemy jak dostał się web2py – jsbueno

Powiązane problemy