[gull] Python-mysqldb

Leopoldo Ghielmetti leopoldo.ghielmetti at a3.epfl.ch
Wed Nov 15 14:24:31 CET 2006


On Wed, 2006-11-15 at 13:23 +0100, Blaise Vogel wrote:
> Bonjour la liste,

salut,

> Je ne suis pas sur que ce sois un bug, donc avant de faire du bruit pour rien 
> j'aimerais bien l'avis d'expert Python.

Je suis loin d'être un expert Python (plutôt un novice), mais je vais
donner mon grain de sel en attendant mieux.

> Pour info:
> Debian Etch / python 2.4
> En insérant des données avec python-mysqldb, j'ai l'erreur suivante:
> ...
> File "/usr/lib/python2.4/site-packages/MySQLdb/cursors.py", line 146, in 
> execute
>     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    

J'ai eu un problème similaire quand j'ai essayé d'écrire un programme
qui devait gérer les caractères UTF8, la solution que j'ai trouvée a été
de:
1. Créer la BD avec le support UTF8.
2. Me connecter à la base en mode UTF8.
3. Activer les charsets UTF8.

En code cela donne:
database = MySQLdb.connect(db=DbParameters[1], host=DbParameters[0],
user=DbParameters[2], passwd=DbParameters[3], unicode="utf8")
c = database.cursor()
c.execute(u"set names utf8")
c.execute(u"set character set utf8")
...
c.close()

Les c.execute suivants dans le ... se font normalement en donnant des
chaînes UTF8 avec un beau .encode("utf8").

c.execute(u"""INSERT INTO la_table VALUES
              (1, 'ma chaîne en utf8')""".encode("utf8"))

Jusqu'à ce qu'on ferme la connection avec la DB avec database.close().

Avant d'y réussir j'ai eu pas mal de peine car Python ne me donnait
jamais une erreur suffisamment claire pour comprendre pourquoi la
conversion n'était pas correcte, et surtout ce que je n'arrives toujours
pas à comprendre c'est pourquoi pour utiliser des chaînes UTF8 dans
Python-MySQLdb il faut utiliser le endode/decode vu que Python lui même
travaille avec de l'UTF8.

Pratiquement je crée une chaîne UTF8 avec u"", puis je la convertis en
UTF8 avec encode et je la passe à la librairie MySQLdb qui effectue les
opérations avec MySQL en UTF8 aussi.
Le résultat que je reçoit de la BD par contre ne nécessite pas de passer
par decode, pratiquement cela donne:

c.execute(u"select id, chaine from ma_table)")

for data in c.fetchall():
  id=data[0]
  chaine=data[1]
  print (id, chaine)

et la chaine semble directement utilisable par Python (mais je n'ai
sûrement pas compris quelque chose).

Je supposes que pour le latin1 ça doit être quelque chose de similaire.

> query = query.encode(charset)
> 
> Mais selon ce que je sais, on doit suivre la régle suivante pour utliser 
> encode/decode:
> 
> utf8 -> decode('utf8') -> unicode -> encode('latin1') -> latin1

C'est logique mais apparemment ce n'est pas ce qui se passe. Je crois
que encode ne fait qu'encoder de l'UTF8 sur de l'unicode et décode fait
l'inverse. Donc tu aurais plutôt quelque chose du style:
utf8 --> encode('utf8') --> unicode --> decode('latin1') --> latin1

> 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 ?

ça je ne l'ais compris moi non plus, il ne fait que générer des erreurs.
Au début j'avais commencé par modifier la librairie pour voir et en
enlevant la ligne tout marchait parfaitement, mais vu que je n'avais pas
envie de me retrouver avec des erreurs avec d'autres logiciels qui
veulent utiliser la même librairie ou avec un futur update de la
librairie elle-même, j'ai ajouté des encode dans mon code pour que le
tout marche quand même.
Mais j'avoue que je n'ai pas compris beaucoup plus que toi.

> Blaise Vogel

J'espère que de t'avoir donné un coup de pouce dans la bonne direction.
Entre-temps moi j'ai eu d'autre choses à faire et je ne me suis plus
préoccupé de ce problème. Mais j'aimerais bien le comprendre une fois
pour toute pour ne plus avoir d'ennuis avec les connections BD.

ciao, Leo

> _______________________________________________
> gull mailing list
> gull at lists.alphanet.ch
> http://lists.alphanet.ch/mailman/listinfo/gull




More information about the gull mailing list