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:
- 'a' est situé après 'X' (les minuscules sont situées après les majuscules),
- 'à' est situé après 'x' (les caractères accentués sont situés après les caractères non accentués).
Solution
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:
- un entier <0 si v1<v2
- 0 si v1==v2
- un entier >0 si v1>v2
Ceci, comme on peut le faire avec la méthode sort() du Python.
Voilà le code proposé (Python 3):
Code PYTHON : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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:
Code : | Sélectionner tout |
1 2 3 4 5 6 | xabc abcç abcé Xabcù Abcè êqsdf |
Code PYTHON : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | cur.execute(""" SELECT * FROM test ORDER BY mots """) datas = cur.fetchall() for data in datas: print data[0] |
Ce qui donne à l'exécution:
Code : | Sélectionner tout |
1 2 3 4 5 6 | Abcè Xabcù abcç abcé xabc êqsdf |
Voilà maintenant le code qui permet de trier dans le bon ordre:
Code PYTHON : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | cnx.create_collation("compdicofr", compdicofr) cur.execute(""" SELECT * FROM test ORDER BY mots COLLATE compdicofr """) datas = cur.fetchall() for data in datas: print data[0] |
Ce qui affiche:
Code : | Sélectionner tout |
1 2 3 4 5 6 | abcç abcé Abcè êqsdf xabc Xabcù |