[gull] Python-mysqldb

Christian Kaenzig christian at becool.ch
Wed Nov 15 14:25:21 CET 2006


On Wednesday, 15 November 2006 13:23, Blaise Vogel wrote:
>     query = query.encode(charset)
> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 2:
> ordinal not in range(128)
> ...
> Et je trouve dans ce fichier à la ligne 146 le code suivant:
> /usr/lib/python2.4/site-packages/MySQLdb/cursors.py
>
> query = query.encode(charset)
>
> Ma chaîne en entrée est en 'latin1'.
> Pour le moment j'ai commenté cette ligne, mais j'avoue ne pas comprendre
> pourquoi ils ont ajouté ce .encode() à cet endroit, pour éviter une
> injection sql ?

Salut. 

Ces histoires d'encodages, c'est vraiment à se tirer le cheveux. De plus en 
plus, les librairies Python sont faites pour fonctionner soit avec des objets 
String contenant uniquement de l'ascii (< 127), ou sinon des objects Unicode. 
Personnellement j'ai été confronté à ça avec simpleTal.

Je pense que c'est dû au fait qu'il est  difficile de déterminer 
automatiquement l'encodage d'une chaine. Donc cette solution est la seule qui 
fonctionne dans tous les cas.

Ton problème vient du fait que tu envoies des chaines (objets String) encodées 
en latin-1. La fonction .encode(charset) va d'abord provoquer le décodage de 
la chaine avant de la réencoder. Mais étant donné que l'encodage n'est pas 
détecté, le "décodeur" ascii est choisi par défaut, et ce dernier ne sais pas 
décoder les caractères > 127 (donc tes accents en latin-1).

Tu peux biensûr commenter les lignes dans mysqldb qui font ce décodage, mais 
pour une solution propre, tu devrais envoyer des objets Unicode à mysqldb. Et 
c'est donc à toi de décoder tes chaines String avec le bon "décodeur" :

mon_unicode = ma_chaine.decode('latin-1')

L'objet Unicode résultant, passé à mysqldb pourra sera encodé par ce dernier 
(sûrement dans un encodage dépendant de la db).

Exemple pratique (ma console est en utf-8, d'où le decode('utf-8') ) :

>>> ma_chaine = "déjà ?"
>>> type(ma_chaine)
<type 'str'>
>>> mon_unicode = ma_chaine.decode('utf-8')
>>> type(mon_unicode)
<type 'unicode'>
>>> mon_unicode
u'd\xe9j\xe0 ?'
>>> print mon_unicode
déjà ?

Bye, a+,
Christian

-- 
Christian Kaenzig
http://chrisk.name/



More information about the gull mailing list