La manière fonctionnelle :
Cette façon montre les fonctions que vous devez configurer pour pouvoir les appeler dans un autre module. J'ai supprimé le gestionnaire de contexte qui ne peut pas être utilisé avec ce modèle fonctionnel, car il se ferme à la fin de la fonction Open_Conn
. Donc le open_conn
la fonction crée un server
objet et l'objet de base de données db
, ils seront ensuite appelés dans close_conn
pour être fermé si nécessaire.
#OpenConn.py
import MySQLdb
from sshtunnel import SSHTunnelForwarder
def open_conn():
server = SSHTunnelForwarder(
('192.168.0.10', 22),
ssh_password="xxx",
ssh_username="xxx",
remote_bind_address=('localhost', 3306))
server.start()
print('opening server : OK')
db = MySQLdb.connect(host='localhost',
port=server.local_bind_port,
user='xxx',
passwd='xxx',
db='DBNAME')
print('opening database : OK')
return (server, db)
def close_conn(server, db):
db.close()
server.stop()
print('closing connection : OK')
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from ViewClientsUI import Ui_ViewClients
from OpenConn import open_conn, close_conn
class ViewClientsWindow(QtWidgets.QDialog, Ui_ViewClients):
def __init__(self):
super(ViewClientsWindow, self).__init__()
self._new_window = None
self.setupUi(self)
self.data_load()
def data_load(self):
server, db = open_conn()
cursor = db.cursor()
query = "SELECT * FROM Clients"
cursor.execute(query)
results = cursor.fetchall()
self.tableWidget.setRowCount(0)
for row_number, row_data in enumerate(results):
self.tableWidget.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.tableWidget.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
close_conn(server, db)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
gui = ViewClientsWindow()
gui.show()
sys.exit(app.exec_())
La méthode du gestionnaire de contexte :
Le modèle fonctionnel peut être amélioré en utilisant une classe de gestionnaire de contexte pour gérer automatiquement l'ouverture et la fermeture. Le gestionnaire ne peut renvoyer que le db.cursor
pour exécuter les requêtes, le serveur reste à l'intérieur du gestionnaire. Pour obtenir le cursor
, vous attrapez la valeur renvoyée par le gestionnaire de contexte dans la méthode __enter__
en utilisant comme :with OpenManager() as cursor:
.
Pour le créer, en gros, vous pouvez déplacer l'ouverture code à l'intérieur de la méthode __enter__
(exécuté lorsque vous appellerez le gestionnaire de contexte) et la fermeture partie à l'intérieur de la méthode __exit__
(appelé à la fin de l'instruction with statement
bloc)
#OpenConn.py
import MySQLdb
from sshtunnel import SSHTunnelForwarder
class OpenManager(object):
def __init__(self):
self.server =None
self.db = None
# here you could define some parameters and call them next
def __enter__(self):
self.server = SSHTunnelForwarder(
('192.168.0.10', 22),
ssh_password="xxx",
ssh_username="xxx",
remote_bind_address=('localhost', 3306))
self.server.start()
print('opening server : OK')
self.db = MySQLdb.connect(host='localhost',
port=self.server.local_bind_port,
user='xxx',
passwd='xxx',
db='DBNAME')
print('opening database : OK')
return self.db.cursor() #
def __exit__(self, type, value, traceback):
self.db.close()
self.server.stop()
print('closing connection : OK')
Ce modèle vous permet d'appeler le gestionnaire de contexte dans votre widget, à l'intérieur d'un with statement
comme ci-dessous :
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from ViewClientsUI import Ui_ViewClients
from OpenConn import OpenManager
class ViewClientsWindow(QtWidgets.QDialog, Ui_ViewClients):
def __init__(self):
super(ViewClientsWindow, self).__init__()
self._new_window = None
self.setupUi(self)
self.data_load()
def data_load(self):
with OpenManager() as cursor:
query = "SELECT * FROM Clients"
cursor.execute(query)
results = cursor.fetchall()
self.tableWidget.setRowCount(0)
for row_number, row_data in enumerate(results):
self.tableWidget.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.tableWidget.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
gui = ViewClientsWindow()
gui.show()
sys.exit(app.exec_())
Vous pouvez également créer la connexion avec SSHTunnelForwarder
directement dans le widget pour éviter cela et utilisez le gestionnaire de contexte fourni par la classe, puis créez la connexion à la base de données à l'intérieur.
La classe personnalisée présentée ci-dessus n'est qu'un moyen de mélanger la connexion au serveur et à la base de données dans un contexte pour faciliter la tâche si vous avez besoin de ces connexions à plusieurs endroits dans votre code.