Convertir un code procédurale en POO [Résolu]

Signaler
Messages postés
122
Date d'inscription
jeudi 20 mars 2014
Statut
Membre
Dernière intervention
30 juillet 2020
-
Messages postés
122
Date d'inscription
jeudi 20 mars 2014
Statut
Membre
Dernière intervention
30 juillet 2020
-
Bonjour,

J'ai une fonction qui permet de sélectionné plusieurs base de donnée dans une répertoire et j'aimerais insérer mon code dans une classe, je connais bien le POO mais je suis bloqué un peu sur ce code qui contient un paramètre personnel *db_names:

import os
import sqlite3
import glob
from os.path import basename, splitext
import os.path
import sys

if not os.path.exists("databases"):
    os.makedirs("databases")
repertoire_contenant_la_base = os.listdir('databases//')

def create_base():
    con = sqlite3.connect("databases/mabase.db")
    cur = con.cursor()
    cur.execute("create table if not exists user(id integer,nom string(25))")
    cur.execute("insert into user(id,nom) values(1,'jean')")
    cur.execute("insert into user(id,nom) values(2,'Jacques')")
    cur.execute("insert into user(id,nom) values(3,'Pierre')")
    con.commit()
    con.close()

def tables_dif(*db_names):
    con = sqlite3.connect(":memory:")
    cur = con.cursor()
    res = {}
    for db_name in db_names:
        con.execute("ATTACH DATABASE './databases/%s' AS db" % db_name)
        sql = '''
                    SELECT  * FROM user
               '''
        cur.execute(sql)
        print(cur.fetchall())
    con.commit()
    con.close()
    return res
create_base()
for repertoire_base in repertoire_contenant_la_base:
        tables_dif(repertoire_base)



Ce que je veux c'est de mettre ce code dans une class Fenetre par exemple et que le résultat soit afficher sur un tableWidget.

Voici le code en POO à la quelle je veux fusionner avec ce premier code:

from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
class Ui_MainWindow(object):

    def loadData(self):
        connexion=sqlite3.connect("databases/mabase.db")
        query="select * from user"
        resultat=connexion.execute(query)
        self.tableWidget.setRowCount(0)
        for row_number,row_data in enumerate(resultat):
            self.tableWidget.insertRow(row_number)
            for column_number,data in enumerate(row_data):
                self.tableWidget.setItem(row_number,column_number,QtWidgets.QTableWidgetItem(str(data)))
        connexion.close()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")

        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(10, 20, 631, 351))
        self.tableWidget.setRowCount(5)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setObjectName("tableWidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(250, 400, 131, 41))
        self.pushButton.setObjectName("pushButton")

        self.pushButton.clicked.connect(self.loadData)

        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Afficher les données"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())




Cordialement!

3 réponses

Messages postés
29356
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
25 octobre 2020
6 951
Bonjour,

À mon avis ce sont surtout deux classes séparées. Voir les préceptes du modèle MVC (Modèle Vue Contrôleur). Si tu respectes une telle architecture, il devient facile d'interchanger sqlite par un autre système de base de données (e.g. mysql ou postgresql).

Donc à mon avis, ton problème est plutôt, comment transformer en objet ton modèle (l'accès à ta base de données). D'un point de vue objets, il faut distinguer l'objet qui permet de te connecter/identifier à la base de la classe qui va envelopper une table de ta base de données. Aujourd'hui dans ton code la connexion et la requête ne sont pas séparées, mais c'est ce qui devrait être fait.

Pour la même raison, la vue (donc la fenêtre) et le cœur du programme sont supposés être deux bouts de code séparés (ce qui permet par exemple de passer à une vue web sans avoir tout à changer).

En effet, si tu manipules plusieurs tables, il n'y a aucune raison de se connecter et reconnecter à chaque requête. On ouvre une connexion au début de la transaction (par exemple au lancement de l'application), et on ferme une fois qu'on a fini (par exemple à la fermeture).

Bonne chance
Messages postés
29356
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
25 octobre 2020
6 951
Voilà à quoi ça pourrait ressembler

class SqlLiteConnector: # ~ Model
  def __init__(self):
    self.con = None
  def connect(self, path):
    self.con = sqlite3.connect(path)
  def create(self):
    # Ton code de création de base de donnée
  def get_table_dif(self, db_name):
    # Ton code dans la boucle for de table_dif

class Ui_MainWindow:
    # En gros la même chose sauf loadData qui sera déporté
class Controller:
  def __init__(self):
    # Code de ton main hormis la partie sur sys.argv
    # Creation de SqlLiteConnector, connection
    # Creation de Ui_MainWindow
    # loadData depuis SqlLiteData
    # Passage de ces données vers Ui_MainWindow
  def loadData(self):
    # Voir ton loadData
Messages postés
122
Date d'inscription
jeudi 20 mars 2014
Statut
Membre
Dernière intervention
30 juillet 2020
1
Merci! je vais essayé de structuré mon code avec, c'est vrai que c'est beaucoup mieux!
Messages postés
122
Date d'inscription
jeudi 20 mars 2014
Statut
Membre
Dernière intervention
30 juillet 2020
1
Merci de votre aide, est j'ai justement l'intention de m'orienter vers le structure MVC mais pour l'instant cela semble très complexe, en attendant j'aimerais juste mettre la fonction create_base() et la fonction tables_dif(*db_names) dans la class Ui_MainWindow(object). Avec un peu de ligne de code cela m'aiderais beaucoup si c'est possible.
Cordialement!