Mysql
 sql >> Base de données >  >> RDS >> Mysql

Python référençant la connexion à la base de données sur un autre script

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.