sql >> データベース >  >> RDS >> Mysql

別のスクリプトでデータベース接続を参照するPython

    機能的な方法:

    このようにして、別のモジュールでそれらを呼び出すことができるように設定する必要のある関数が表示されます。関数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つのコンテキスト内で混合して、コード内の多くの場所でこれらの接続が必要な場合に簡単にする方法にすぎません。




    1. php mysqli_connect:クライアントに不明な認証方法[caching_sha2_password]

    2. read()を呼び出す前にフィールドにアクセスしようとする試みが無効です

    3. テーブルの行ごとに1つの区切り文字列を作成しながら、CLOB(XMLを含む)から特定の値を抽出します。一部の行ではCLOB値がnullになる場合があります

    4. ストアドプロシージャを使用して選択したい値を取得できません