QSqlDatabase sshtunnel зависает

помогите пожалуйста, пытаюсь подключиться через ssh к postgresql и передать данные в qsqlrelationaltablemodel, при выполнении кода ниже программа зависает без вывода каких-либо ошибок пока я ее не завершу вручную, все переменные удаляются. Зависает на исполнении команд self.conn.tables() и self.Sqlmodel.setTable(self.tblName). При этом стандартные query выполняются на отлично! Коннект с БД есть. В примере использовал qsqltablemodel для упрощения. Также уже пробовал оборачивать подключение к ssh и подключение к бд в отдельные потоки, не помогает, также происходит зависание.

Чуть изменил код, была ошибка со строками, но всё равно зависает.

    import sys
    from sshtunnel import SSHTunnelForwarder
    import sshtunnel
    sshtunnel.SSH_TIMEOUT = 5.0
    sshtunnel.TUNNEL_TIMEOUT = 5.0
    sshtunnel.DEFAULT_LOGLEVEL=40
    from PyQt5 import QtWidgets, QtSql
    from PyQt5.QtSql import QSqlTableModel, QSqlDatabase
    
    class ServerConnect():
        def __init__(self, sshHost, sshPort, sshUsr, localport, usr, pwd, hst, dbName, tblName):
            self.port = None
            self.conn = None
            self.Sqlmodel = None
            
            self.sshHost=sshHost
            self.sshPort=sshPort
            self.sshUsr=sshUsr
            self.localport=localport
            self.usr = usr
            self.pwd = pwd
            self.hst = hst
            self.dbName = dbName      
            self.tblName=tblName
            self.run()
            self.postgreSqlCon()
            
            
        def run(self):    
            try:
                print('Соединение с сервером. Подождите...')
                self.sshtunnel = SSHTunnelForwarder(
                    ssh_address_or_host=(self.sshHost, self.sshPort),
                    ssh_username=self.sshUsr,
                    remote_bind_address=(self.hst, self.localport),
                    threaded=True,
                    ssh_proxy_enabled=False,
                    set_keepalive=10
                    )
                self.sshtunnel.start()
                self.port = self.sshtunnel.local_bind_port
                print('Соединение установлено.')              
            except:
                print('Ошибка соединения.') 
    
        def postgreSqlCon(self):
            if self.port != None:
                self.conn = QSqlDatabase.addDatabase("QPSQL7")
                self.conn.setUserName(self.usr)
                self.conn.setPassword(self.pwd)
                self.conn.setHostName(self.hst)
                self.conn.setPort(self.port)
                self.conn.setDatabaseName(self.dbName)
                print(self.conn.connectionNames())
                self.conn.open()
                #print(self.conn.tables())
                if self.conn.open():
                    self.Sqlmodel = QSqlTableModel()
                    name = []
                    self.query = QtSql.QSqlQuery(f'SELECT "name" FROM '"{self.tblName}"')
                    while self.query.next():
                        name.append(self.query.value(0))
                    print(name)
                    
                    self.Sqlmodel.setTable(f'"{self.tblName}"')
                    self.Sqlmodel.select()
                    print(self.Sqlmodel.lastError().text())
                    print(self.Sqlmodel.rowCount())   
                    self.conn.close()
                    self.sshtunnel.stop()     
                    return self.Sqlmodel
            
    if __name__ == '__main__':
        sshHost, sshPort, sshUsr = '***', 22, '***'
        localport=5432
        usr, pwd, hst, dbName, tblName = "***", "***", "127.0.0.1", "***", "***"
        
        app = QtWidgets.QApplication(sys.argv) 
        window = QtWidgets.QWidget() 
        window.setWindowTitle("QSqlTableModel")  
        stm = ServerConnect(sshHost, sshPort, sshUsr, localport, usr, pwd, hst, dbName, tblName)
        vbox = QtWidgets.QVBoxLayout() 
        tv = QtWidgets.QTableView() 
        tv.setModel(stm)    
        vbox.addWidget(tv) 
        window.setLayout(vbox) 
        window.resize(300, 250) 
        window.show()
        sys.exit(app.exec_())

Спасибо.


Ответы (1 шт):

Автор решения: alex_guest

К данному вопросу добавлю, что проблема заключается в невозможности передать данные после соединения с SSH и QSqlDataBase в модель.

После успешного подключения работает SQlQuery, получается извлечь и обработать любую информацию, но при передаче данных в модель QSqlTableModel или QSqlQueryModel все зависает.

Пробовали .setQuery(self.query) или .setRecord(self.query.record()) или, как в примере выше self.Sqlmodel.setTable(f'"{self.tblName}"') - не работает.

Думаю, нужно получить данные из Query в массив данных и оттуда в модель, но тогда для QSqlTableModel нужно создать свой subclass, что пока затруднительно.

→ Ссылка