Mysql
 sql >> Database >  >> RDS >> Mysql

Connessione al database di riferimento Python su un altro script

Il modo funzionale:

In questo modo vengono mostrate le funzioni che è necessario impostare per poterle richiamare in un altro modulo. Ho rimosso il gestore del contesto che non può essere utilizzato con questo pattern funzionale, poiché viene chiuso alla fine della funzione Open_Conn . Quindi il open_conn la funzione crea un server oggetto e l'oggetto database db , verranno chiamati successivamente in close_conn chiudersi quando necessario.

#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_())

Il modo di gestione del contesto:

Il modello funzionale può essere migliorato utilizzando una classe di gestione del contesto per gestire automaticamente l'apertura e la parte di chiusura. Il gestore può restituire solo il db.cursor per eseguire le query, il server rimane all'interno del gestore. Per ottenere il cursor , catturi il valore restituito dal gestore del contesto all'interno del metodo __enter__ utilizzando come :with OpenManager() as cursor: .

Per crearlo, in pratica, puoi spostare l'apertura codice all'interno del metodo __enter__ (eseguito quando chiamerai il gestore del contesto) e la chiusura parte all'interno del metodo __exit__ (chiamato alla fine del with statement blocco)

#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')

Questo modello ti consente di chiamare il gestore del contesto nel tuo widget, all'interno di un with statement come di seguito:

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_())

Puoi anche creare la connessione con SSHTunnelForwarder direttamente nel widget per evitare ciò e utilizzare il gestore di contesto fornito dalla classe, quindi creare la connessione al database all'interno.

La classe personalizzata mostrata sopra è solo un modo per combinare la connessione al server e al database all'interno di un contesto per semplificare se hai bisogno di queste connessioni in molti punti del tuo codice.