2012-11-07 16 views
6

Creo un database in mysql e utilizzo webpy per costruire il mio server web.Perché il cinese è confuso quando si usa webpy ma è normale quando si utilizza MySQLdb?

Ma è così strano per il carattere cinese tra i comportamenti di webpy e MySQLdb quando li utilizza per accedere rispettivamente al database.

Qui di seguito è il mio problema:

Il mio tavolo t_test (utf8 databse):

id  name 
1  测试 

il codice utf8 per "测试" è: \ XE6 \ XB5 \ x8b \ xe8 \ XAF \ x95

quando si utilizza MySQLdb di fare "selezionare" in questo modo:

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

il risultato è normale, stampa:

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

Ma quando uso webpy fare le stesse cose:

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

garble cinese si è verificato, il risultato di stampa è: banca dati

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

So di webpy dipende anche MySQLdb, ma è così diverso per questi due modi. Perché?

BTW, per la ragione sopra, posso semplicemente usare MySQLdb direttamente per risolvere il mio problema di caratteri cinesi, ma perde il nome della colonna nella tabella - È così ingrato. Voglio sapere come posso risolverlo con webpy?

+2

Infatti, la stringa che si recupera viene visualizzata solo per i rifiuti. Forse i dati nella base dati non sono codificati in utf-8? Come è stato registrato lì? – jsbueno

+0

Sono sicuro che i dati nel mio database sono anche utf-8. Uso Navicat per controllare la mia tabella mysql e il codice esadecimale per "测试" è: E6B5 8BE8 AF95. E inoltre, potresti usare UtraEdit per verificarlo. @jsbueno – eason

+0

Non sono sicuro se rilevante, ma questo è quello che ottengo quando stampo la stringa incomprensibile: http://codepad.org/o3DgYhxr, æμ <è¯ • invece di 忙碌 鈥 姑  €. Dove stai stampando la tua stringa? –

risposta

1

Infatti, qualcosa di molto sbagliato si sta verificando - come hai detto sul tuo commento, l'unicode repr. byte per "测试" sono E6B5 8BE8 AF95 - che lavora sul mio terminale utf-8 qui:

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

Ma guardate i byte sul vostro "commento" oggetto unicode:

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

parte Significato dei contenuti sono i byte UTF-8 per il commento (i caratteri rappresentati come "\ XYY" e parte è codificato come Unicode points (i Chares rappresentati con \ uYYYY) - questo indica serio spazzatura

MySQL ha. qualche gatto chs alla decodifica corretta (utf-8 o altrimenti) codificato testo in esso - uno dei quali passa un parametro "charset" corretto alla connessione. Ma lo hai già fatto -

Un tentativo che puoi fare è passare la connessione l'opzione use_unicode=False - e decodificare le stringhe utf-8 nel tuo codice.

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

Controllare le opzioni per la connessione per questo e altri parametri che si potrebbe provare:

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

Indipendentemente a farla funzionare correttamente, con i suggerimenti di cui sopra, ho ottenuto una soluzione per tu - Sembra che i caratteri Unicode (non i byte grezzi utf-8 negli oggetti unicode) nella stringa codificata siano codificati in una di queste codifiche: ("cp1258", "cp1252", "palmos", " cp1254 ")

Di questi, cp1252 è quasi lo stesso di "latin1" - che è il set di caratteri predefinito MySQL utilizza se non ottiene l'argomento "charset" nella connessione. Ma non è solo questione di web2py non passarlo al database, dato che stai ricevendo caratteri storpiati, non solo la codifica sbagliata - è come se web2py stia codificando e decodificando la tua stringa avanti e indietro, e ignorando gli errori di codifica

Da tutte queste codifiche ho potuto recuperare il "测试" stringa originale, come una stringa di byte UTF-8, facendo, ad esempio:

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

Quindi, mettendo questa linea potrebbe funzionare per voi, ma indovinare intorno con unicode non è mai una buona cosa - la cosa proepr è restringere ciò che sta facendo web2py per darti quelle stringhe utf-8 semi-decodificate sul primo posto, e fallo fermare lì.

aggiornamento

ho controllato qui- questo è ciò che sta accadendo - la corretta utf-8 '\xe6\xb5\x8b\xe8\xaf\x95' stringa viene letto dal mysql, e prima di consegnare a voi, (nel caso use_unicode = True) 0 - questi byte vengono decodificati come se fossero "cp1252" - questo produce l'unicode u'\xe6\xb5\u2039\xe8\xaf\u2022' errato. È probabilmente un errore web2py, come, non passa il parametro "charset = utf8" alla connessione effettiva. Quando si imposta "use_unicode = False" invece di fornire i byte non elaborati, apparentemente seleziona l'unicode errato, un dencode che utilizza "utf-8" - questo produce la sequenza '\xc3\xa6\xc2\xb5\xe2\x80\xb9\xc3\xa8\xc2\xaf\xe2\x80\xa2' commentata qui di seguito (che è ancora più errata) .

tutto sommato, la soluzione che ho citato sopra sembra l'unico modo per recuperare la, corretta stringa originale -cioè, data l'unicode sbagliato, farlo u'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore") - cioè, a corto di fare qualche altra cosa da set-up la connessione al database (o forse aggiornare i driver di web2py o MySQL, se possibile)

** aggiornamento ** 2 ho futrher controllato il codice in web2py dal.py file stesso - tenta di impostare la connessione come UTF-8 di default - ma sembra che proverà entrambi i driver MySQLdb e pymysql - se entrambi hai installato prova a disinstallare pymysql e lascia solo MySQLdb.

+0

Grazie per l'analisi dettagliata! Dal momento che non può funzionare dopo i 2 passaggi che hai dato, è ancora istruttivo. Quando ho impostato la connessione con "use_unicode = False", ho ricevuto repr (commento) del tipo: \ xc3 \ xa6 \ xc2 \ xb5 \ xe2 \ x80 \ xb9 \ xc3 \ xa8 \ xc2 \ xaf \ xe2 \ x80 \ xa2, è NON codifica utf8. Quindi lo codifico con cp1252 (ignore), ma non è ancora riuscito. BTW: Nella mia domanda iniziale, quello che intendevo per "STRANO" è esattamente semi utf8 e semi unicode quando si usa webpy, come hai detto prima. Quindi, penso che sia un bug di webpy. – eason

+0

Se si tenta di decodificare la sequenza di cui sopra come se fosse in cui in utf-8, si arriva a ciò che si ottiene previoulsy: 'u '\ xe6 \ xb5 \ u2039 \ xe8 \ xaf \ u2022'' -ora almeno lo sappiamo come è arrivato web2py – jsbueno

Problemi correlati