Cách chức năng:
Cách này hiển thị các chức năng bạn cần thiết lập để có thể gọi chúng trong một mô-đun khác. Tôi đã xóa trình quản lý ngữ cảnh không thể sử dụng với mẫu chức năng này, vì nó bị đóng ở cuối hàm Open_Conn
. Vì vậy, open_conn
hàm tạo một máy chủ server
đối tượng và đối tượng cơ sở dữ liệu db
, chúng sẽ được gọi tiếp theo trong close_conn
đóng cửa khi cần thiết.
#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_())
Cách quản lý ngữ cảnh:
Mẫu chức năng có thể được cải thiện bằng cách sử dụng lớp trình quản lý ngữ cảnh để xử lý phần mở và phần đóng một cách tự động. Người quản lý chỉ có thể trả về db.cursor
để thực hiện các truy vấn, máy chủ vẫn ở bên trong trình quản lý. Để lấy cursor
, bạn bắt được giá trị trả về bởi trình quản lý ngữ cảnh bên trong phương thức __enter__
bằng cách sử dụng as :with OpenManager() as cursor:
.
Để tạo nó, về cơ bản, bạn có thể di chuyển mở mã bên trong phương thức __enter__
(được thực thi khi bạn gọi trình quản lý ngữ cảnh) và đóng phần bên trong phương thức __exit__
(được gọi ở cuối with statement
khối)
#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')
Mẫu này cho phép bạn gọi trình quản lý ngữ cảnh trong tiện ích con của mình, bên trong with statement
như bên dưới:
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_())
Bạn cũng có thể tạo kết nối với SSHTunnelForwarder
trực tiếp trong tiện ích con để tránh điều này và sử dụng trình quản lý ngữ cảnh do lớp cung cấp, sau đó tạo kết nối cơ sở dữ liệu bên trong.
Lớp tùy chỉnh được hiển thị ở trên chỉ là một cách để kết hợp kết nối với máy chủ và với cơ sở dữ liệu bên trong một ngữ cảnh để dễ dàng thực hiện nếu bạn cần những kết nối này ở nhiều vị trí trong mã của mình.