Python et Cassandra : erreur « Ordinal not range »

de | 2017-05-05

Pour changer des articles sur Cassandra, nous allons parler aujourd’hui de ce problème que vous avez peut-être déjà rencontré lors d’une requête avec cqlsh, l’outil client de… Cassandra. Désolé, nous avons vraiment essayé de parler d’autre chose mais les évènements nous ont rattrapés. Prenez-le comme un investissement pour l’avenir. Un jour, peut-être, vous serez content de retrouver cet article.

Bref, tâchons d’être synthétiques.

Le problème

Lors d’un import de données (« COPY … FROM… ») ou d’un simple « DESCRIBE SCHEMA; » / « DESCRIBE KEYSPACE … », la commande échoue avec ce message :

'ascii' codec can't encode characters in position 41988-41989: ordinal not in range(128)

Breaking news ! Après recherche, cela vient de la version de Python intégrée dans notre Centos 6 : 2.6.6. Sur les machines en Centos 7, le problème de se présente plus. Mettez à jour si vous pouvez (juste Python si possible), migrez… ou évitez les accents !

La cause

Il s’agit d’un problème fréquent avec Python.

Lors de la lecture d’une chaîne stockée en UTF8 et lorsque la sortie est à tort considérée à tort en ASCII, Python tente de convertir silencieusement les caractères. Cela fonctionne seulement jusqu’à ce qu’il rencontre un caractère étendu – tel qu’un accent – auquel cas il ne trouve pas d’équivalent dans la table de conversion et retourne l’erreur.

La résolution

Mais pourquoi décider de convertir UTF8 vers ASCII ?

Il y a plusieurs explications qui dépendent de votre contexte. En pur Python, cela peut venir d’une chaîne qui n’est pas déclarée en Unicode. Plus largement, cela peut provenir d’un enchaînement d’imports qui s’écrasent et induisent l’interpréteur en erreur.

Pour cqlsh, c’est le cas. Le chargement de la librairie de décodage est annulé, et l’interpréteur se rabat sur le mode ASCII, ce qui passe inaperçu dans un environnement majoritairement anglophone. Malheureusement pour nous, certaines tables comportaient des commentaires en français, donc avec des accents.

Nous avons contourné le problème en créant une copie de cqlsh (qui est un script Python) et en rechargeant la librairie de décodage avec ces lignes :

cqlsh : patch express

cqlsh : patch express

Ce qui a permis de nous débloquer.

Conclusion

Modifier une partir d’un script fourni en standard dans un programme reste une solution temporaire : soit vous modifiez l’original – et ça sera écrasé lors d’une mise à jour – , soit vous faites une version alternative mais devrez gérer son évolution.

De plus, cela ne répond que partiellement à la question : comment peut-on se retrouver dans ce genre de situation en utilisant un langage qui intègre l’UTF8 depuis le tout début ?

Nos connaissances en Python ne sont pas suffisantes pour nous permettre de comprendre précisément la cause de ce comportement. Recharger la librairie nous suffisait mais ce ne sera pas toujours le cas. Et il y a quelques inconvénients qui empêchent de considérer le problème réglé.

Plus d’informations dans l’article qui nous a sauvé la journée (en anglais). Vous vous doutez que nous n’avons pas trouvé cette astuce tous seuls !

Au final, le seul vrai conseil : ne mettez pas d’accents dans vos commentaires ! Restez à l’anglais !

Des problèmes ? des questions ? Exprimez-vous ! Les commentaires sont ouverts. Coquilles et fautes de grammaires sont notre lot quotidien : signalez-les nous à m.capello@dbsqware.com