Convertir un code procédurale en POO

Résolu/Fermé
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 - 21 févr. 2020 à 13:43
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 - 25 févr. 2020 à 13:46
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!
A voir également:

3 réponses

mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
23 févr. 2020 à 14:01
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
1
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
24 févr. 2020 à 11:16
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
1
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 9
25 févr. 2020 à 13:46
Merci! je vais essayé de structuré mon code avec, c'est vrai que c'est beaucoup mieux!
0
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 9
24 févr. 2020 à 07:04
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!
0