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 :

Fermer connection avec base de données


Sujet :

PyQt Python

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Par défaut Fermer connection avec base de données
    Bonjour,

    Je me permet de vous soliciter parce que je suis en train de faire des testes pour mettre mon application en relation avec une base de données MySQL.

    J'ai créé une petite boite de dialogue qui affiche et permet de modifier le contenu d'une table de ma base de données.

    Voilà mon code :
    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
     
    import os
    import sys
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    from PyQt4.QtSql import *
    from PyQt4.Qt import *
     
     
    NUMMANIP, NOMS, REFCAHIER, TAILLE, NBITER, PCIBLE, FENETRE, COLLIMATEUR, ENERGIE, FAISCEAU, COMPTEUR, OBJECTIF, COMMENTAIRE, MODE = range(14)
     
    class ManipDlg(QDialog):
     
        def __init__(self):
            super(ManipDlg, self).__init__()
     
            self.db = None
            self.manipView = QTableView()
            self.openDatabase()
     
            buttonsBox = QDialogButtonBox()
            addButton = buttonsBox.addButton("Ajouter", QDialogButtonBox.ActionRole)
            deleteButton = buttonsBox.addButton("Supprimer", QDialogButtonBox.ActionRole)
     
     
            layout = QVBoxLayout()
            layout.addWidget(self.manipView)
            layout.addWidget(buttonsBox)
            self.setLayout(layout)
     
        def openDatabase(self):
     
            if self.db:
                self.closeDatabase()
     
            self.db = QSqlDatabase.addDatabase("QMYSQL")
            self.db.setHostName("host")
            self.db.setUserName("root")
            self.db.setPassword("xxxx")
            self.db.setDatabaseName("DiamTestAnalyse_db")
     
            if not self.db.open():
                QMessageBox.warning(None, "Reference Data",
                    "Database Error: {}".format(self.db.lastError().text()))
                sys.exit(1)
     
            self.manipModel = QSqlRelationalTableModel(self)
            self.manipModel.setTable("manip")
            self.manipModel.setSort(NUMMANIP, Qt.DescendingOrder)
            self.manipModel.setHeaderData(NUMMANIP, Qt.Horizontal, QVariant("numManip"))
            self.manipModel.setHeaderData(NOMS, Qt.Horizontal, QVariant("noms"))
            self.manipModel.setHeaderData(REFCAHIER, Qt.Horizontal, QVariant("refCahier"))
            self.manipModel.setHeaderData(TAILLE, Qt.Horizontal, QVariant("taille"))
            self.manipModel.setHeaderData(NBITER, Qt.Horizontal, QVariant("nbIter"))
            self.manipModel.setHeaderData(PCIBLE, Qt.Horizontal, QVariant("Pcible"))
            self.manipModel.setHeaderData(FENETRE, Qt.Horizontal, QVariant("fenetre"))
            self.manipModel.setHeaderData(COLLIMATEUR, Qt.Horizontal, QVariant("collimateur"))
            self.manipModel.setHeaderData(ENERGIE, Qt.Horizontal, QVariant("energie"))
            self.manipModel.setHeaderData(FAISCEAU, Qt.Horizontal, QVariant("faisceau"))
            self.manipModel.setHeaderData(COMPTEUR, Qt.Horizontal, QVariant("compteur"))
            self.manipModel.setHeaderData(OBJECTIF, Qt.Horizontal, QVariant("objectif"))
            self.manipModel.setHeaderData(COMMENTAIRE, Qt.Horizontal, QVariant("commentaire"))
            self.manipModel.setHeaderData(MODE, Qt.Horizontal, QVariant("mode"))
            self.manipModel.setEditStrategy(QSqlTableModel.OnFieldChange)
            self.manipModel.select()
     
            self.manipView.setModel(self.manipModel)
            self.manipView.setSelectionMode(QTableView.SingleSelection)
            self.manipView.setSelectionBehavior(QTableView.SelectRows)
            self.manipView.resizeColumnsToContents()
     
     
        def closeDatabase(self):
     
            self.manipView.setModel(None)
            del self.manipModel
            self.db.close()
            dbConnectionName = self.db.connectionName()
            self.db = QSqlDatabase()
            self.db.removeDatabase(dbConnectionName)
     
        def closeEvent(self, event):
            self.closeDatabase()
     
     
    def main():
        app = QApplication(sys.argv)    
     
        form = ManipDlg()
        form.show()
     
        sys.exit(app.exec_())
     
    if __name__ == "__main__": 
        main()
    J'ai un message d'erreur qui apparait à la fermeture de mon application pour me dire que j'ai encore des requètes en cours. Pourtant j'ai supprimé le Model qui accède aux données !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    Je donne ma langue au chat sur ce coup là...

    Merci pour votre aide

  2. #2
    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


    Je n'ai jamais travaillé avecMySql, uniquement QSQlite et je n'ai jamais eu ce message d'erreur.

    De plus je viens de faire un test avec une BDD SQlite, et je n'ai pas non plus ce message.

    Donc je dirai plus un souci avec MySql. C'est une obligation de travailler avec ce DBMS ?

    Par contre je ne vois pas la ligne :
    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

  3. #3
    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,

    J'ai eu ce warning avec sqlite3 (Pthon 2.7 - PyQt4), et j'ai mis pas mal de temps à le supprimer. Voilà ce que j'utilise actuellement:

    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
        def closeEvent(self, event=None):
            """Méthode appelée automatiquement en cas de demande d'arrêt"""
     
            # force la sortie du mode édition si en cours (modifs perdues)
            self.ui.vuetable.reset()
     
            # fermer la connexion à la base de données (si elle est ouverte)
            if self.cnx != None:
                try:
                    # couper la liaison entre le QTableView et le model
                    self.ui.vuetable.setModel(None)
     
                    # détruire le model et libérer ses ressources
                    self.model.clear()
                    del self.model
     
                    # détruire la connection et libérer ses ressources
                    self.cnx.close()
                    self.cnx = None
     
                except:
                    pass # en cas d'erreur: ne rien faire!   
     
            # et accepter la fermeture de la fenêtre
            event.accept()
    Dans ce code:
    self.ui.vuetable: le QTableView
    self.model: le QSqlRelationalTableModel
    self.cnx: la connexion

    Curieusement, la fermeture de la connexion semble suffire (dans mon contexte) et je n'utilise plus le ".removeDatabase". Cependant, s'il était nécessaire avec MySql, j'ai déjà utilisé ce complément:

    A l'établissement de la connexion, on donne un nom (ici: "db1"):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.cnx = QSqlDatabase.addDatabase("QSQLITE", "db1")
    Ce qui permet, après la fermeture de la connexion, de détruire le lien avec la base en utilisant ce nom:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QSqlDatabase.removeDatabase("db1")
    De plus, en cas d'utilisation de requête (query=QSqlQuery()), il ne faut oublier de la libérer à la fin dans le même bloc de code avec query.finish().

    Pour Jiyuu: le "open" est à la ligne 42 ("if not self.db.open():").

  4. #4
    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
    Pour Jiyuu: le "open" est à la ligne 42 ("if not self.db.open():").
    J'ai peut-être stoppé la programmation trop longtemps, mais pour moi ça c'est pas une "action" mais une condition.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if not self.db.open():
        QMessageBox.warning(None, "Reference Data", "Database Error: {}".format(self.db.lastError().text()))
        sys.exit(1)
    Moi par ces lignes je comprends :
    Si self.db pas ouvert, alors j'affiche un QMeesageBox.
    Sinon pour revenir au problème voici mon code sous Python 3 et PyQt5, mais je rappelle que je n'ai jamais eu ce soucis même sous PyQt4 :

    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
     
    import os
    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtSql import *
    from PyQt5.Qt import *
     
     
    NUMMANIP, NOMS, REFCAHIER, TAILLE, NBITER, PCIBLE, FENETRE, COLLIMATEUR, ENERGIE, FAISCEAU, COMPTEUR, OBJECTIF, COMMENTAIRE, MODE = range(14)
     
    class ManipDlg(QDialog):
     
        def __init__(self):
            super(ManipDlg, self).__init__()
     
            self.db = None
            self.manipView = QTableView()
            self.openDatabase()
     
            buttonsBox = QDialogButtonBox()
            addButton = buttonsBox.addButton("Ajouter", QDialogButtonBox.ActionRole)
            deleteButton = buttonsBox.addButton("Supprimer", QDialogButtonBox.ActionRole)
     
     
            layout = QVBoxLayout()
            layout.addWidget(self.manipView)
            layout.addWidget(buttonsBox)
            self.setLayout(layout)
     
            self.openDatabase()
     
        def openDatabase(self):
     
            if self.db:
                self.closeDatabase()
     
            self.db = QSqlDatabase.addDatabase("QSQLITE")
            self.db.setDatabaseName("base.db")
            self.db.open()
     
            if not self.db.open():
                QMessageBox.warning(None, "Reference Data",
                    "Database Error: {}".format(self.db.lastError().text()))
                sys.exit(1)
     
            self.manipModel = QSqlRelationalTableModel(self)
            self.manipModel.setTable("manip")
            self.manipModel.setSort(NUMMANIP, Qt.DescendingOrder)
            self.manipModel.setHeaderData(NUMMANIP, Qt.Horizontal, QVariant("numManip"))
            self.manipModel.setHeaderData(NOMS, Qt.Horizontal, QVariant("noms"))
            self.manipModel.setHeaderData(REFCAHIER, Qt.Horizontal, QVariant("refCahier"))
            self.manipModel.setHeaderData(TAILLE, Qt.Horizontal, QVariant("taille"))
            self.manipModel.setHeaderData(NBITER, Qt.Horizontal, QVariant("nbIter"))
            self.manipModel.setHeaderData(PCIBLE, Qt.Horizontal, QVariant("Pcible"))
            self.manipModel.setHeaderData(FENETRE, Qt.Horizontal, QVariant("fenetre"))
            self.manipModel.setHeaderData(COLLIMATEUR, Qt.Horizontal, QVariant("collimateur"))
            self.manipModel.setHeaderData(ENERGIE, Qt.Horizontal, QVariant("energie"))
            self.manipModel.setHeaderData(FAISCEAU, Qt.Horizontal, QVariant("faisceau"))
            self.manipModel.setHeaderData(COMPTEUR, Qt.Horizontal, QVariant("compteur"))
            self.manipModel.setHeaderData(OBJECTIF, Qt.Horizontal, QVariant("objectif"))
            self.manipModel.setHeaderData(COMMENTAIRE, Qt.Horizontal, QVariant("commentaire"))
            self.manipModel.setHeaderData(MODE, Qt.Horizontal, QVariant("mode"))
            self.manipModel.setEditStrategy(QSqlTableModel.OnFieldChange)
            self.manipModel.select()
     
            self.manipView.setModel(self.manipModel)
            self.manipView.setSelectionMode(QTableView.SingleSelection)
            self.manipView.setSelectionBehavior(QTableView.SelectRows)
            self.manipView.resizeColumnsToContents()
     
     
        def closeDatabase(self):
            print ('1')
     
            self.manipView.setModel(None)
            del self.manipModel
            self.db.close()
            dbConnectionName = self.db.connectionName()
            self.db = QSqlDatabase()
            self.db.removeDatabase(dbConnectionName)
     
        def closeEvent(self, event):
            self.closeDatabase()
     
     
    def main():
        app = QApplication(sys.argv)    
     
        form = ManipDlg()
        form.show()
     
        sys.exit(app.exec_())
     
    if __name__ == "__main__": 
        main()
    Question hors sujet : tes imports tu les fais tout le temps comme ça ?

    @+
    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

  5. #5
    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 Jiyuu

    Citation Envoyé par Jiyuu Voir le message
    ...
    mais pour moi ça c'est pas une "action" mais une condition
    ...
    Ici, cest une action qui renvoie une condition (et c'est conforme au manuel).

  6. #6
    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
    Il va falloir que je rebouquine mes bases moi

    EDIT :
    Après petite réflexion, je pense que je suis allé un peu vite en besogne... Ceci n'est effectivement pas une condition à proprement parler puisque il n'y a pas de comparateur (!= ,==, ...).

    En plus j'ai bien du déjà utiliser cette façon de faire.

    Comme quoi rien ne sert de courir ^^
    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

Discussions similaires

  1. Comment se connecter à une base de données oracle avec Talend?
    Par shark84 dans le forum Développement de jobs
    Réponses: 8
    Dernier message: 16/09/2011, 10h13
  2. Réponses: 10
    Dernier message: 10/06/2009, 13h26
  3. Réponses: 0
    Dernier message: 05/12/2007, 06h20
  4. Réponses: 3
    Dernier message: 06/09/2007, 10h29
  5. [ADO.NET] Problème avec ma connection à la base de données
    Par gibea00 dans le forum Accès aux données
    Réponses: 2
    Dernier message: 07/12/2006, 20h03

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