機能的な方法:
このようにして、別のモジュールでそれらを呼び出すことができるように設定する必要のある関数が表示されます。関数Open_Conn
の最後で閉じられるため、この関数パターンで使用できないコンテキストマネージャーを削除しました 。したがって、open_conn
関数はserver
を作成します オブジェクト、およびデータベースオブジェクトdb
、次にclose_conn
で呼び出されます 必要に応じて閉鎖します。
#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_())
コンテキストマネージャーの方法:
コンテキストマネージャークラスを使用して開始部分と終了部分を自動的に処理することにより、機能パターンを改善できます。マネージャはdb.cursor
のみを返すことができます クエリを実行するために、サーバーはマネージャー内にとどまります。 cursor
を取得するには 、メソッド__enter__
内のコンテキストマネージャーによって返される値をキャッチします asを使用する :with OpenManager() as cursor:
。
作成するには、基本的に、開口部を移動できます メソッド__enter__
内のコード (コンテキストマネージャーを呼び出すときに実行されます)および終了 メソッド__exit__
内の一部 (with statement
の最後に呼び出されます ブロック)
#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')
このパターンを使用すると、ウィジェット内のwith statement
内でコンテキストマネージャーを呼び出すことができます。 以下のように:
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_())
SSHTunnelForwarder
を使用して接続を作成することもできます これを回避するためにウィジェットで直接、クラスによって提供されるコンテキストマネージャーを使用してから、内部にデータベース接続を作成します。
上記のカスタムクラスは、サーバーへの接続とデータベースへの接続を1つのコンテキスト内で混合して、コード内の多くの場所でこれらの接続が必要な場合に簡単にする方法にすぎません。