sql >> Base de Datos >  >> RDS >> Mysql

Python que hace referencia a la conexión de la base de datos en otro script

La forma funcional:

De esta manera muestra las funciones que necesita configurar para poder llamarlas en otro módulo. Eliminé el administrador de contexto que no se puede usar con este patrón funcional, ya que se cierra al final de la función Open_Conn . Entonces el open_conn la función crea un server objeto, y el objeto de la base de datos db , serán llamados a continuación en close_conn para cerrar cuando sea necesario.

#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 forma del administrador de contexto:

El patrón funcional se puede mejorar utilizando una clase de administrador de contexto para manejar la parte de apertura y cierre automáticamente. El administrador solo puede devolver el db.cursor para ejecutar las consultas, el servidor permanece dentro del administrador. Para obtener cursor , captura el valor devuelto por el administrador de contexto dentro del método __enter__ usando como :with OpenManager() as cursor: .

Para crearlo, básicamente, puedes mover la apertura código dentro del método __enter__ (ejecutado cuando llamará al administrador de contexto) y el cierre parte dentro del método __exit__ (llamado al final de la declaración with statement bloque)

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

Este patrón le permite llamar al administrador de contexto en su widget, dentro de una declaración with statement como a continuación:

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

También puede crear la conexión con SSHTunnelForwarder directamente en el widget para evitar esto y use el administrador de contexto provisto por la clase, luego cree la conexión de la base de datos dentro.

La clase personalizada que se muestra arriba es solo una forma de combinar la conexión con el servidor y la base de datos dentro de un contexto para que sea más fácil si necesita estas conexiones en muchos lugares de su código.