IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Filtre partiel de recherche [QtSql]


Sujet :

PyQt Python

  1. #1
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut Filtre partiel de recherche


    Imaginons que dans une table nommée test d'une base de données quelconques j'ai les entrées suivantes :

    - entrée n°1 : id : 1 ; val : '12345" ; com : "test1"
    - entrée n°2 : id : 2 ; val : '23456" ; com : "test2"
    - entrée n°3 : id : 3 ; val : '45679" ; com : "test3"


    Je n'ai rien trouvé de base dans Qt Sql permettant de filtrer toutes les entrées dont val contient 34. Est-ce que je suis passé à coté de quelques choses ?

    Si effectivement rien n'existe cela risque de signifier qu'il va me falloir passer par du Regex : soit directement dans la requête Sql, avec sûrement des adaptations, soit en important toute la base sous forme de liste de liste et en filtrant après chaque sous-liste... à voir ce qui sera le plus performant en termes de rapidité d'exécution.

    Pour le moment pas besoin de vous casser la tête à trouver une solution en Regex... j'aimerai juste savoir si je passe à coté de quelques choses de "natif".

    D'avance merci à tous.

    J
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je n'ai pas le temps de chercher tout de suite, mais il me semble que ça existe dans les fonctions SQL. Regarde dans la doc de sqlite3 qui est assez claire: http://www.sqlite.org/lang.html

    Si tu n'as pas trouvé cet après-midi, je creuserai un peu. J'ai déjà fait pas mal de choses dans ce domaine (y compris des recherches de mots "similaires", avec ratio de similitude, dans une base).

  3. #3
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Re,

    Merci Tyrtamos. Je n'ai pas du tout pensé à regarder de ce coté. Sachant que QSqlTableModel hérite de QSqlQueryModel on peut en effet passé des "vraies" commandes Sql ce qui donne à priori dans mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    model = QtSql.QSqlTableModel()
    model.setQuery(QtSql.QSqlQuery("SELECT * FROM test WHERE val REGEXP '.*34.*'"))
    model.select()
    Malheureusement cela ne me renvoie aucune entrée.

    J'ai testé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    model = QtSql.QSqlTableModel()
    model.setQuery(QtSql.QSqlQuery("SELECT * FROM test WHERE val LIKE '12345'"))
    model.select()
    et là j'ai bien quelque chose.

    Je continue à creuser car cela vient sûrement de ma REGEX (c'est pour ça que je voulais éviter ça ), mais si jamais tu vois une grosse erreur de ma part hésite pas.
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Essaie ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select *
    from test
    where test.val like "%34%"
    En fait, like fait une recherche de type "wilcard", mais avec d'autres caractères: '%' au lieu de '*', et '_' au lieu de '?'. Voir ici d'autres subtilités: http://www.tutorialspoint.com/sqlite...ike_clause.htm.

  5. #5
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Nikel, mais pas besoin du test.valà priori.

    Par contre c'est étrange que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "SELECT * FROM test WHERE val REGEXP '.*34.*'"
    ne fonctionne pas...la REGEX est bien bonne pourtant, non ?
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Jiyuu Voir le message
    Par contre c'est étrange que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "SELECT * FROM test WHERE val REGEXP '.*34.*'"
    ne fonctionne pas...la REGEX est bien bonne pourtant, non ?
    Désolé, je ne peux pas essayer: REGEXP n'est pas implanté dans sqlite3.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Désolé, je ne peux pas essayer: REGEXP n'est pas implanté dans sqlite3.
    Il l'est mais ca redirige vers une fonction/callback utilisateur a déclarer "avant".
    Bizarre que Qt ne remonte pas une erreur.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Il l'est mais ca redirige vers une fonction/callback utilisateur a déclarer "avant".
    C'est une autre façon de dire la même chose, puisque tant qu'une telle fonction n'a pas été ajoutée, ça ne donne aucun résultat (j'ai une erreur chez moi).

    Avec le pilote sqlite3 de Python, on peut facilement ajouter une telle fonction Python avec "create_function" (j'ai d'ailleurs tendance à abuser de ce genre de technique).

    Mais avec le pilote sqlite3 de Qt, l'ajout devrait être fait, me semble-t-il, en C++, ce qui n'est pas de même niveau de complexité.

  9. #9
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Il l'est mais ca redirige vers une fonction/callback utilisateur a déclarer "avant".
    Bizarre que Qt ne remonte pas une erreur.
    - W
    J'ai pas fait gaffe à ça... car je confirme que j'utilise bien sqlite3 et qu'aucune erreur n'est remontée.

    Cela est à creuser, mais dans l'immédiat la solution de Tyrtamos donne bonne satisfaction.

    Merci à vous 2
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Mais avec le pilote sqlite3 de Qt, l'ajout devrait être fait, me semble-t-il, en C++, ce qui n'est pas de même niveau de complexité.
    Pour construire le code, il faudra récupérer des headers et une DLL sqlite3 compatible avec celle qui est built in dans Qt.
    Ce n'est pas trop complique mais c'est du boulot.
    Et il faudra recommencer a chaque mise a jour de Qt.

    Citation Envoyé par Jiyuu
    J'ai pas fait gaffe à ça... car je confirme que j'utilise bien sqlite3 et qu'aucune erreur n'est remontée.

    Cela est à creuser, mais dans l'immédiat la solution de Tyrtamos donne bonne satisfaction.
    N'oubliez pas d'indexer la colonne.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pour construire le code, il faudra récupérer des headers et une DLL sqlite3 compatible avec celle qui est built in dans Qt.
    Merci wiztricks. C'est bien ce que je pensais: tant que je peux faire autrement, j'éviterai ça.

    Petit complément.

    En fait, j'essaie toujours d'ajouter les fonctions qui me manquent dans le SQL, sans aller jusqu'à faire ça en C/C++. Voilà ma logique appliquée dans un programme PyQt4:

    - quand j'utilise du graphique pour me connecter à la base (consultation / modification / tri / filtrage / recherche / ...), par exemple avec un QTableView, j'utilise un delegate (QtSql.QSqlRelationalDelegate), un modèle (QtSql.QSqlRelationalTableModel) mais aussi un proxy (QtGui.QSortFilterProxyModel), les 3 sous-classés, et c'est dans le proxy que j'ajoute les méthodes de tri ou de filtrage supplémentaires (je n'ai pas dit que c'était simple...). Mais les fonctions supplémentaires sont alors pilotées par le graphique, et non par le script SQL lui-même.

    - quand je n'utilise pas de graphique pour agir sur la base, même dans un programme PyQt4, j'utilise le pilote sqlite3 de Python directement, ce qui me permet d'ajouter les fonctions qui manquent avec les méthodes prévues: create_function, create_aggregate et create_collation. Ce dernier permet, par exemple, d'ajouter une méthode de tri selon le dictionnaire français. Les fonctions ainsi ajoutées peuvent être directement utilisées dans le script SQL.

    Mais, bien sûr, avec sqlite3, la base n'est jamais ouverte en même temps avec les 2 pilotes!!!

    Par exemple, dans les 2 cas, j'ajoute de quoi chercher des mots similaires avec ratio de similitude (avec difflib.SequenceMatcher), ce qui me permet de trouver des noms qui auraient pu avoir été mal saisis au clavier avec erreur sur un ou deux caractère(s): je ne connais pas d'autre méthode pour faire ça, et je dois dire que ça marche drôlement bien.

  12. #12
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Merci wiztricks. C'est bien ce que je pensais: tant que je peux faire autrement, j'éviterai ça.
    Une chose est sûre c'est que moi aussi je vais éviter ça, déjà parce que si peux l'éviter tant mieux et surtout parce qu'à ce jour j'en suis parfaitement incapable

    Citation Envoyé par tyrtamos Voir le message
    j'utilise du graphique pour me connecter à la base (consultation / modification / tri / filtrage / recherche / ...), par exemple avec un QTableView, j'utilise un delegate (QtSql.QSqlRelationalDelegate), un modèle (QtSql.QSqlRelationalTableModel) mais aussi un proxy (QtGui.QSortFilterProxyModel), les 3 sous-classés, et c'est dans le proxy que j'ajoute les méthodes de tri ou de filtrage supplémentaires (je n'ai pas dit que c'était simple...). Mais les fonctions supplémentaires sont alors pilotées par le graphique, et non par le script SQL lui-même.
    Tout dépend du niveau de complexité je pense. Si c'est uniquement pour une recherche sur une colonne d'une table je pense qu'un simple setFilter suffit. Enfin c'est comme ça que j'ai fait jusqu'à maintenant.

    Mais maintenant j'ai besoin de faire des recherches un peu plus poussées comme des recherches partielles dans plusieurs colonnes voir plusieurs tables. Tu penses qu'il est préférable de passer par autre chose qu'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from test where val like "%34%"
    avec plusieurs critères de recherches ? (si c'est faisable évidemment).
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  13. #13
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Jiyuu Voir le message
    Mais maintenant j'ai besoin de faire des recherches un peu plus poussées comme des recherches partielles dans plusieurs colonnes voir plusieurs tables. Tu penses qu'il est préférable de passer par autre chose qu'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from test where val like "%34%"
    avec plusieurs critères de recherches ? (si c'est faisable évidemment).
    Dit comme tu le fais, je ne pense pas. C'est quand même la vocation de SQL de faire des recherches avec des conditions complexes. Commence donc par exploiter toutes les possibilités des scripts SQL: au fur et à mesure qu'on essaie, on est étonné de la puissance de ce truc. Même si sqlite3 ne se trouve qu'au niveau de la norme SQL92, procure toi un bon livre des techniques SQL, et essaie! Il y a par exemple des choses à faire avec les "sous-requêtes" corrélées ou non.

    Par exemple, dans l'un de mes programmes, j'ai un script SQL qui me fait des statistiques complexes: en 5 secondes, j'obtiens un tableau qui me demanderait au moins 2 ou 3 heures à faire autrement sous Excel (avec risques d'erreur de calcul dans la recopie...).

    A noter qu'il y a des infos sur SQL dans developpez: http://sgbd.developpez.com/.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Macro filtre élaboré probleme recherche
    Par exile69 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 26/09/2014, 11h19
  2. filtre partiel ds une table ado
    Par chiheb79 dans le forum Bases de données
    Réponses: 8
    Dernier message: 04/11/2009, 16h37
  3. Réponses: 6
    Dernier message: 18/06/2008, 16h49
  4. critere de filtre et de recherche commun
    Par alsimbad dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 20/06/2007, 17h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo