PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

UnicodeDecodeError:il codec 'ascii' non può decodificare il byte 0x92 nella posizione 47:ordinale non compreso nell'intervallo(128)

Il problema è che stai chiamando encode su un str oggetto.

Un str è una stringa di byte, che di solito rappresenta il testo codificato in qualche modo come UTF-8. Quando chiami encode su questo, deve prima essere decodificato in testo, in modo che il testo possa essere ricodificato. Per impostazione predefinita, Python lo fa chiamando s.decode(sys.getgetdefaultencoding()) e getdefaultencoding() di solito restituisce 'ascii' .

Quindi, stai parlando di testo codificato UTF-8, decodificandolo come se fosse ASCII, quindi ricodificandolo in UTF-8.

La soluzione generale è chiamare esplicitamente decode con la giusta codifica, invece di lasciare che Python usi il default, e poi encode il risultato.

Ma quando la codifica giusta è già quella che desideri, la soluzione più semplice è semplicemente saltare il .decode('utf-8').encode('utf-8') e usa semplicemente UTF-8 str come UTF-8 str lo è già.

O, in alternativa, se il tuo wrapper MySQL ha una funzione che ti consente di specificare una codifica e tornare unicode valori per CHAR /VARCHAR /TEXT colonne invece di str valori (ad esempio, in MySQLdb, passi use_unicode=True al connect call o charset='UTF-8' se il tuo database è troppo vecchio per rilevarlo automaticamente), fallo. Allora avrai unicode oggetti e puoi chiamare .encode('utf-8') su di loro.

In generale, il modo migliore per affrontare i problemi Unicode è l'ultimo:decodificare tutto il prima possibile, eseguire tutte le elaborazioni in Unicode e quindi codificare il più tardi possibile. Ma in ogni caso, devi essere coerente. Non chiamare str su qualcosa che potrebbe essere un unicode; non concatenare un str letterale a un unicode oppure passane uno al suo replace metodo; ecc. Ogni volta che mescoli e abbini, Python convertirà implicitamente per te, usando la tua codifica predefinita, che non è quasi mai quella che vuoi.

Come nota a margine, questa è una delle tante cose con cui le modifiche Unicode di Python 3.x aiutano. Innanzitutto, str è ora testo Unicode, non byte codificati. Ancora più importante, se hai byte codificati, ad esempio, in un bytes oggetto, chiamando encode ti darà un AttributeError invece di provare a decodificare silenziosamente in modo che possa ricodificare. E, allo stesso modo, provare a mescolare e abbinare Unicode e byte ti darà un ovvio TypeError , invece di una conversione implicita che in alcuni casi riesce e fornisce un messaggio criptico su una codifica o decodifica che non hai richiesto in altri.