A maneira funcional:
Desta forma, mostra as funções que você precisa configurar para poder chamá-las em outro módulo. Eu removi o gerenciador de contexto que não pode ser usado com este padrão funcional, pois ele é fechado no final da função
Open_Conn
. Portanto, o open_conn
função cria um server
objeto e o objeto de banco de dados db
, eles serão chamados em seguida em close_conn
fechar quando necessário. #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_())
A maneira do gerenciador de contexto:
O padrão funcional pode ser melhorado usando uma classe de gerenciador de contexto para manipular a abertura e a parte de fechamento automaticamente. O gerente pode retornar apenas o
db.cursor
para executar as consultas, o servidor fica dentro do gerenciador. Para obter o cursor
, você pega o valor retornado pelo gerenciador de contexto dentro do método __enter__
usando como :with OpenManager() as cursor:
. Para criá-lo, basicamente, você pode mover a abertura código dentro do método
__enter__
(executado quando você chamará o gerenciador de contexto) e o fechamento parte dentro do método __exit__
(chamado no final da instrução with statement
quadra) #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 padrão permite que você chame o gerenciador de contexto em seu widget, dentro de um
with statement
como abaixo: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_())
Você também pode criar a conexão com
SSHTunnelForwarder
diretamente no widget para evitar isso e use o gerenciador de contexto fornecido pela classe, então crie a conexão de banco de dados dentro. A classe personalizada mostrada acima é apenas uma maneira de misturar a conexão com o servidor e o banco de dados dentro de um contexto para facilitar se você precisar dessas conexões em vários locais do seu código.