PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

UnicodeDecodeError :le codec 'ascii' ne peut pas décoder l'octet 0x92 en position 47 :ordinal hors plage (128)

Le problème est que vous appelez encode sur une str objet.

Une str est une chaîne d'octets, représentant généralement du texte codé d'une manière ou d'une autre comme UTF-8. Lorsque vous appelez encode sur ce point, il doit d'abord être décodé en texte, afin que le texte puisse être réencodé. Par défaut, Python le fait en appelant s.decode(sys.getgetdefaultencoding()) , et getdefaultencoding() renvoie généralement 'ascii' .

Donc, vous parlez de texte encodé en UTF-8, en le décodant comme s'il s'agissait d'ASCII, puis en le réencodant en UTF-8.

La solution générale consiste à appeler explicitement decode avec le bon encodage, au lieu de laisser Python utiliser la valeur par défaut, puis encode le résultat.

Mais lorsque le bon encodage est déjà celui que vous voulez, la solution la plus simple est de simplement ignorer le .decode('utf-8').encode('utf-8') et utilisez simplement l'UTF-8 str comme UTF-8 str qu'il l'est déjà.

Ou, alternativement, si votre wrapper MySQL a une fonctionnalité pour vous permettre de spécifier un encodage et de récupérer unicode valeurs pour CHAR /VARCHAR /TEXT colonnes au lieu de str valeurs (par exemple, dans MySQLdb, vous passez use_unicode=True au connect appel, ou charset='UTF-8' si votre base de données est trop ancienne pour la détecter automatiquement), faites-le. Ensuite, vous aurez unicode objets, et vous pouvez appeler .encode('utf-8') sur eux.

En général, la meilleure façon de traiter les problèmes Unicode est la dernière :tout décoder le plus tôt possible, effectuer tout le traitement en Unicode, puis encoder le plus tard possible. Mais dans tous les cas, il faut être cohérent. N'appelez pas str sur quelque chose qui pourrait être un unicode; ne pas concaténer un str littéral à un unicode ou passez-en un à son replace méthode; etc. Chaque fois que vous mélangez et faites correspondre, Python va implicitement convertir pour vous, en utilisant votre encodage par défaut, qui n'est presque jamais ce que vous voulez.

En passant, c'est l'une des nombreuses choses avec lesquelles les changements Unicode de Python 3.x aident. Tout d'abord, str est maintenant du texte Unicode, et non des octets codés. Plus important encore, si vous avez octets codés, par exemple, dans un bytes objet, appelant encode vous donnera une AttributeError au lieu d'essayer de décoder silencieusement afin qu'il puisse ré-encoder. Et, de la même manière, essayer de mélanger et de faire correspondre Unicode et des octets vous donnera une évidente TypeError , au lieu d'une conversion implicite qui réussit dans certains cas et donne un message crypté sur un encodage ou un décodage que vous n'avez pas demandé dans d'autres.