[Refonte de la page le 3/3/2015. Passage à Python 3]
Quand on veut extraire d'une base SQL des informations texte triées en utilisant 'ORDER BY', on se heurte au problème habituel: l'ordre de tri coïncide avec l'ordre des caractères dans les polices de caractères, c'est à dire, par exemple, que:
Pour trier selon l'alphabet français, et en fait, selon l'alphabet qu'on veut, on va créer une fonction de comparaison comme cmp(v1, v2), c'est à dire qui compare v1 et v2 et qui renvoie:
Ceci, comme on peut le faire avec la méthode sort() du Python.
Voilà le code proposé (Python 3):
import locale ############################################################################# class Compdicofr(object): """comparaison de 2 chaines selon le dictionnaire français""" def __init__(self): self.loc = locale.getlocale() # stocke la locale courante self.espinsec = '\xA0' # espace insécable def __call__(self, v1, v2): # on retire les tirets et les blancs insécables v1 = v1.replace('-', '') v1 = v1.replace(self.espinsec, '') v2 = v2.replace('-', '') v2 = v2.replace(self.espinsec, '') # on fait la comparaison selon la locale locale.setlocale(locale.LC_ALL, '') comp = locale.strcoll(v1, v2) # retour à la locale initiale locale.setlocale(locale.LC_ALL, self.loc) # on retourne le résultat de la comparaison return comp compdicofr = Compdicofr()
Prenons maintenant un exemple: on crée une base sqlite3 contenant une table “test” avec un champ “mots” contenant dans l'ordre d'introduction:
xabc abcç abcé Xabcù Abcè êqsdf
Voilà le code pour extraire ces données et les présenter dans l'ordre de tri habituel:
cur.execute(""" SELECT * FROM test ORDER BY mot """) datas = cur.fetchall() for data in datas: print data[0]
Ce qui donne à l'exécution:
Abcè Xabcù abcç abcé xabc êqsdf
Vous constatez que ce n'est pas terrible: le 'a' est après le 'X' et le 'ê' est après le 'x'…
Voilà maintenant le code qui permet de trier dans le bon ordre:
cnx.create_collation("compdicofr", compdicofr) cur.execute(""" SELECT * FROM test ORDER BY mot COLLATE compdicofr """) datas = cur.fetchall() for data in datas: print data[0]
Ce qui affiche:
abcç abcé Abcè êqsdf xabc Xabcù
C'est quand même autre chose, non?
Amusez-vous bien!