sql >> Databasteknik >  >> RDS >> Mysql

Python som refererar till databasanslutning på ett annat skript

Det funktionella sättet:

På så sätt visas de funktioner du behöver ställa in för att kunna anropa dem i en annan modul. Jag tog bort sammanhangshanteraren som inte kan användas med detta funktionsmönster, eftersom den stängs i slutet av funktionen Open_Conn . Så open_conn funktionen skapar en server objekt och databasobjektet db , kommer de att anropas härnäst i close_conn för att stängas vid behov.

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

Kontexthanterarens sätt:

Det funktionella mönstret kan förbättras genom att använda en kontexthanterarklass för att hantera öppnings- och stängningsdelen automatiskt. Hanteraren kan endast returnera db.cursor för att köra frågorna stannar servern i managern. För att få cursor , fångar du värderetur av kontexthanteraren i metoden __enter__ genom att använda som :with OpenManager() as cursor: .

För att skapa den kan du i princip flytta öppningen kod inuti metoden __enter__ (körs när du kommer att anropa kontexthanteraren) och avslutningen del i metoden __exit__ (anropas i slutet av with statement blockera)

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

Detta mönster låter dig anropa kontexthanteraren i din widget, inuti en with statement som nedan :

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

Du kan också skapa anslutningen med SSHTunnelForwarder direkt i widgeten för att undvika detta och använd kontexthanteraren som tillhandahålls av klassen, skapa sedan databasanslutningen inuti.

Den anpassade klassen som visas ovan är bara ett sätt att blanda anslutningen till servern och till databasen i ett sammanhang för att göra det enkelt om du behöver dessa anslutningar på många ställen i din kod.




  1. Hur bestämmer man värdnamnet i Oracle APEX?

  2. Hur man installerar SQL Server Manager Studio (SSMS) - SQL Server / TSQL självstudie del 1

  3. Hur sparar man flera repeterbara fält som array i databasen?

  4. Kan inte ansluta till Vagrant med HeidiSQL:Kan inte ansluta till MySQL-server på "localhost"