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 :

Affichage résultat requête sql dans un QTableView [QtSql]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Par défaut Affichage résultat requête sql dans un QTableView
    Bonjour,

    En résumé, je voudrais affiché le résultat d'une requête SQL pour le calcul de l'écart-type.
    Ainsi, je crée une table view à partir d'une requête et je voudrais l'afficher QTableView.

    A vrai dire, la requête est compliquée, elle s'affiche dans SQLiteStudio mais sur la QTableView rien ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
       # view tmp_ecarts_types
     
        cursor_creation_tmp_ecarts_types = connexion_creation.cursor()
        cursor_creation_tmp_ecarts_types.execute('''DROP VIEW IF EXISTS tmp_ecarts_types''')
        cursor_creation_tmp_ecarts_types.execute('''CREATE VIEW tmp_ecarts_types AS SELECT a.reference, a.intitule 
        AS contrat, b.periode, b.variance, round(sqrt(b.variance), 2) AS ecart_type 
        FROM clients a , (SELECT m.reference, m.periode, m.phase1, m.phase2, m.phase3, 
        round(cast(pow(abs(m.moyenne - m.Taux1),2)/3 AS real)) AS valeur1,  
        round(cast(pow(abs(m.moyenne - m.Taux2),2)/3 AS real)) AS valeur2, 
        round(cast(pow(abs(m.moyenne - m.Taux3),2)/3 AS real)) AS valeur3, 
        round(pow(abs(m.moyenne - m.Taux1),2)/3 
        + pow(abs(m.moyenne - m.Taux2),2)/3 
        + pow(abs(m.moyenne - m.Taux3),2)/3,2) AS variance 
        FROM (SELECT reference, periode, E_phase1 AS phase1, E_phase2 AS phase2, E_phase3 AS phase3, totalisateur AS total,
        round(cast(E_phase1 AS float)/(totalisateur)*100, 2) AS Taux1,
        round(cast(E_phase2 AS float)/(totalisateur)*100, 2) AS Taux2,
        round(cast(E_phase3 AS float)/(totalisateur)*100, 2) AS Taux3,
        round(CASE WHEN reference <>"" THEN  
        (round(cast(E_phase1 AS float)/(totalisateur)*100) 
        + round(cast(E_phase2 AS float)/(totalisateur)*100) 
        + round(cast(E_phase3 AS float)/(totalisateur)*100))/3 ELSE 0 END,2) AS moyenne
        FROM tmp_ecarts_phases
        ORDER BY reference, periode) AS m 
        ORDER BY reference, periode) AS b 
        WHERE a.reference = b.reference 
        ORDER BY a.reference, b.periode ''')
    Nom : ecarts_types.png
Affichages : 1096
Taille : 6,6 Ko

    Vous voudrez bien m'aider ? Est ce que j'ai oublié un truc ou bien c'est une limite du sqlite3
    il faut vous préciser, qu'il y a d'autres tables plus consistante mais, elles s'affichent le plus simple du monde dans le QTableView.

    Merci.

  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,

    A ma connaissance, QTableView ne s'intéresse qu'à la table une fois constituée, et non à la requête qui l'a créée. Il faudrait donc vérifier avec un logiciel adapté que la table a une structure et un contenu correct, et sinon, revoir la requête (il suffit d'une virgule mal placée...).

    D'ailleurs, sous Python avec le pilote sqlite3 de Python (et non celui de PyQt5!), il est possible "d'éplucher" chaque table de la base de donnée pour voir son contenu.

    Voilà un petit exemple tout simple pour faire ça avec Python:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import os
    import sqlite3
     
    #############################################################################
    def base2script(base, script, codage='utf-8'):
        """permet de convertir une base de données sqlite3 en script SQL
           base: la base de données (nom du fichier avec son chemin)
           script: le script SQL à créer (nom du fichier avec son chemin)
           codage: encodage du script SQL à créer
        """
     
        # affiche dans la console
        print("Conversion de la base SQL en script SQL:")
        print()
        print("base SQL:  ", base)
        print("script SQL:", script)
        print()
     
        # ouvre la base de données sqlite3
        try:
            cnx = sqlite3.connect(base)
        except sqlite3.Error as err:
            print("Echec pour la connexion à la base de données\n" + err.args[0])
            return
     
        # convertit la base sqlite3 en script SQL
        with open(script, 'w', encoding=codage) as f:
            nbl = 0 # compteur de lignes
            for i, ligne in enumerate(cnx.iterdump()):
                nbl += 1
                f.write('%s\n' % (ligne,))
     
        # ferme la base
        cnx.close()
     
        # message de fin
        print("le script SQL fait %d lignes" % nbl)
        print("Conversion terminée!")
        print() 
     
    #############################################################################
    def script2base(script, base, codage='utf-8-sig'):
        """permet de convertir un script SQL en base de données sqlite3
           script: le script SQL (le nom du fichier avec son chemin)
           base: la base de données (nom du fichier avec son chemin)
           codage: encodage du script SQL à exploiter
        """
     
        # affiche dans la console
        print("Conversion du script SQL en base de données sqlite3")
        print() 
        print("script SQL:  ", script)
        print("base SQL:", base)
        print()
     
        # lit le script sql
        with open(script, 'r', encoding=codage) as f:
            scriptsql = f.read()
     
        # ouvre la base de données sqlite3
        try:
            cnx = sqlite3.connect(base)
            cur = cnx.cursor()
        except sqlite3.Error as err:
            print("Echec pour la connexion à la base de données\n" + err.args[0])
            return
     
        # exécute le script pour reconstruire la base de données sqlite3
        try:
            cur.executescript(scriptsql)
        except sqlite3.Error as err:
            print("Erreur dans l'exécution du script\n" + err.args[0])
            cur.close()
            cnx.close()
            print("conversion non réalisée!")
            return
     
        # ferme la base de données
        cur.close()
        cnx.close()
     
        # message de fin
        print("conversion terminée!")
     
    #############################################################################
    if __name__ == "__main__":
     
        base = "mabase.db3"
        script = "mabase2.txt"
        base2script(base, script)
     
     
        script = "mabase2.txt"
        base = "mabase2.db3"
        if os.path.exists(base):
            os.remove(base) 
        script2base(script, base)
    A lancer dans une console pour avoir les affichages. Exemple d'affichage (base de données complexe avec 19 tables et des contraintes diverses entre les tables):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Conversion de la base SQL en script SQL:
     
    base SQL:   mabase.db3
    script SQL: mabase2.txt
     
    le script SQL fait 5195 lignes
    Conversion terminée!
     
    Conversion du script SQL en base de données sqlite3
     
    script SQL:   mabase2.txt
    base SQL: mabase2.db3
     
    conversion terminée!
    Le principe est simple:

    - base2script => on a la base sqlite3 "mabase.db3", on la convertit en script SQL (=liste des requêtes!) => "mabase2.txt".

    - script2base => on reprend ensuite ce même script "ma base2.txt", et on refabrique la base initiale => "mabase2.db3" qui devrait donner le même résultat que la base originale. Attention cependant: s'il y a des contraintes de clés étrangères, l'ordre de re-création des tables devra être compatible avec ces contraintes!

    Amélioration possible: exécution de chaque requête séparée pour identifier la ligne des éventuelles erreurs.

    A noter qu'en faisant ça, on se donne la possibilité de changer la structure de la base de données, alors que les commandes SQL de sqlite3 pour faire ça sont très limitées.

  3. #3
    Membre confirmé
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Par défaut
    Merci Tyrtamos pour votre réponse, à vrai dire c'est toujours vous qui commence le bal des réponses,

    Comme je l'ai dit, j'ai crée une table view à partir d'une requête, la vue s'affiche bien dans SQLiteStudio après quelques secondes de traitement, se qui prouve que la requête est correcte.
    Et je veux l'afficher dans la QTableView comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
            self.model_analyse_types = QSqlRelationalTableModel(self)
            self.model_analyse_types.setTable("tmp_ecarts_types")
            self.model_analyse_types.select()
            self.model_analyse_types.setHeaderData(0, Qt.Horizontal, "REFERENCE")
            self.model_analyse_types.setHeaderData(1, Qt.Horizontal, "INTITULE")
            self.model_analyse_types.setHeaderData(2, Qt.Horizontal, "PERIODE")
            self.model_analyse_types.setHeaderData(3, Qt.Horizontal, "VARIANCE")
            self.model_analyse_types.setHeaderData(4, Qt.Horizontal, "ECART-TYPE")
            self.model_analyse_types.setSort(0, Qt.AscendingOrder)
     
            while self.model_analyse_types.canFetchMore():
                self.model_analyse_types.fetchMore()
     
            self.ui.tableView_types.setModel(self.model_analyse_types)
            self.ui.tableView_types.setSortingEnabled(True)
            self.ui.tableView_types.resizeColumnsToContents()
            self.ui.tableView_types.resizeRowsToContents()
     
            self.ui.tableView_types.hideColumn(0)
            self.ui.tableView_types.hideColumn(1)

  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
    Bonjour

    Voilà une version très simplifiée de l'affichage d'une table de base de données sqlite3 dans un QTableView:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    """
    Affichage d'une table d'une base de données sqlite3 dans un QTableView
    """
     
    import sys
    import os
    from PyQt5 import (QtWidgets, QtGui, QtCore, QtSql)
     
    #############################################################################
    def ouvrebaseqt(basesql):
        """Ouvre la base sqlite3 'basesql' sous PyQt et renvoie la connexion
           Si échec, retourne None
        """
        db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName(basesql)
        if not db.open():
            db = None # Erreur d'ouverture de la base de données basesql
        return db # retourne la connexion (=None si échec)
     
    #############################################################################
    def fermebaseqt(db):
        """Ferme la base ouverte avec la connexion db 
        """
        db.close()
        db.removeDatabase(db.databaseName())
     
    #############################################################################
    class VueTable(QtWidgets.QTableView):
        """visualise une table d'une base de données sqlite3 ouverte
        """
        # nouveau signal pour indiquer la fin d'affichage à l'appelant
        finvuetable = QtCore.pyqtSignal(int)
     
        #========================================================================
        def __init__(self, db, nomtable, indexfin=0, parent=None):
            super().__init__(parent)
            self.resize(600, 400)
     
            self.db = db # connexion à la base de données
            self.nomtable = nomtable # nom de la table à afficher
            self.indexfin = indexfin # index de la fenêtre VueTable
     
            self.model = QtSql.QSqlRelationalTableModel(self, self.db)
            self.model.setTable(self.nomtable)
            self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) #OnManualSubmit)
            self.model.select()
            while self.model.canFetchMore():
                self.model.fetchMore()
     
            self.setModel(self.model)
            self.setItemDelegate(QtSql.QSqlRelationalDelegate(self))
            self.setSortingEnabled(True)
            self.resizeColumnsToContents()
     
            # Change la police de caractères
            font = QtGui.QFont()
            font.setFamily("DejaVu Sans Mono")
            font.setPointSize(10)
            self.setFont(font)
     
            self.setWindowTitle("Table: " + self.nomtable)
     
        #========================================================================
        def closeEvent(self, event):
            """fermeture de la fenêtre
            """
            # envoi du signal de fermeture à l'appelant
            self.finvuetable.emit(self.indexfin)
            # et accepte la fermeture
            event.accept()
     
    #========================================================================
    def infofinvuetable(indfin):
        """Exécuté à la fermeture de la fenêtre VueTable
        """
        # simple affichage en console
        print("Affichage terminé pour la fenêtre ", indfin)
     
        # ferme la base ouverte
        fermebaseqt(db) 
     
    #############################################################################
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
     
         # ouverture de la base à utiliser
        basesql = "mabase.db3" 
        db = ouvrebaseqt(basesql)
        if db==None:
            QtWidgets.QMessageBox.critical(None, 
                    "Ouverture de la base", 
                    " ====> Echec <==== ")
            app.quit()
            sys.exit()
     
        # affiche la table
        vuetable = VueTable(db, "matable")
        # la fermeture de la fenêtre entrainera l'exécution de infofinvuetable
        vuetable.finvuetable.connect(infofinvuetable)
        vuetable.show()
     
        sys.exit(app.exec_())
    Regarde si ça marche avec ta base.

  5. #5
    Membre confirmé
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Par défaut
    Bonjour Tyrtamos,

    J'ai utilisé votre code sa ne marche pas En utilisant une autre view son contenu s'affiche normalement.

  6. #6
    Membre confirmé
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Par défaut
    Bonjour Tyrtamos,

    J'ai voulu contourné le problème en insérant le contenu de la vue dans une autre vue temporaire et le message suivant s'affiche :
    sqlite3.OperationalError: no such function: pow
    c'est un problème lié avec la fonction pow

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

Discussions similaires

  1. [MySQL] Affichage résultat requête SQL dans page HTML comme un tableau
    Par joxbl dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 14/03/2011, 14h26
  2. Affichage résultat requête SQL
    Par Shankara dans le forum Composants
    Réponses: 7
    Dernier message: 10/06/2010, 21h21
  3. [AC-2003] Récupération résultats requête SQL dans VBA
    Par rberniga dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 19/08/2009, 11h28
  4. Réponses: 2
    Dernier message: 14/03/2008, 17h02
  5. Réponses: 13
    Dernier message: 28/09/2007, 11h55

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