Как вывести результат запроса из БД в QTableView?

Пишу desktop приложение. В качестве графического интерфейса использую Pyside6, БД - postgresql, ORM - sqlalchemy.
В таблице клиентов порядка 100 000 записей. На данный момент для вывода общего списка клиентов использую QTableWidget.

Текущий вариант заполнения таблицы:

self.ui.tableWidget.setRowCount(0)
        session = Session()
        System.all_clients = session.query(Client).order_by(Client.id)
        for client in System.all_clients:
            row = self.ui.tableWidget.rowCount()
            self.ui.tableWidget.insertRow(row)
            self.ui.tableWidget.setItem(row, 0, QTableWidgetItem(f"{client.id}"))
            self.ui.tableWidget.setItem(row, 1, QTableWidgetItem(f"{client.last_name}"))
            self.ui.tableWidget.setItem(row, 2, QTableWidgetItem(f"{client.first_name}"))
            self.ui.tableWidget.setItem(row, 3, QTableWidgetItem(f"{client.middle_name}"))
            self.ui.tableWidget.setItem(row, 4, QTableWidgetItem(f"{client.gender}"))
            self.ui.tableWidget.setItem(row, 5, QTableWidgetItem(f"{client.birth_date}"))
            self.ui.tableWidget.setItem(row, 6, QTableWidgetItem(f"{client.privilege}"))
            self.ui.tableWidget.setItem(row, 7, QTableWidgetItem(f"{client.phone}"))
            self.ui.tableWidget.setItem(row, 8, QTableWidgetItem(f"{client.email}"))
        session.close()

Вроде бы, QTableView работает быстрее. И было бы логично использовать его, используя фильтрацию по какому-либо столбцу (вместо выполнения очередного запроса). Подскажите, пожалуйста, как вывести результат запроса в QTableView?


Update 12.03.22 13:48

Изменил в предложенном [S.Nick][1] варианте подключение к БД. Но коннекта нет.

app = QtWidgets.QApplication(sys.argv)
db = QtSql.QSqlDatabase.addDatabase("QPSQL")  # !!! установите свое
db.setHostName("192.168.x.x")
db.setPort(5432)
db.setDatabaseName("database")  # !!! установите свое
db.setUserName("postgres")
db.setPassword("xxx")
db.open()

Хотя если сделать такую операцию:

dbliste = QtSql.QSqlDatabase.drivers()
print(dbliste)

То показываются следующие драйвера: ['QSQLITE', 'QODBC', 'QPSQL']


Update 14.03.22 16:07

import sys
from PySide6 import QtCore, QtGui, QtWidgets, QtSql
# import psycopg2

class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.lineEdit = QtWidgets.QLineEdit()
        self.comboBox = QtWidgets.QComboBox()
        self.tableView = QtWidgets.QTableView()
        # self.model = QtSql.QSqlTableModel()
        # self.tableView.setModel(self.model)
        self.model = QtSql.QSqlTableModel(self.tableView, db)
        table_name = 'client'  # !!! установите свою таблицу
        self.model.setTable(table_name)
        self.model.select()

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.lineEdit, 0, 0)
        grid.addWidget(self.comboBox, 0, 1)
        grid.addWidget(self.tableView, 1, 0, 1, 2)

        # self.model.setTable("client")  # !!! установите свою таблицу
        # self.model.select()

        self.comboBox.clear()
        for i in range(self.model.columnCount()):
            self.comboBox.addItem(self.model.headerData(i, QtCore.Qt.Horizontal))

        self.lineEdit.textChanged.connect(self.filter_table)

    def filter_table(self, text):
        filter = " {} LIKE '%{}%'".format(self.comboBox.currentText(), text) if text else text
        self.model.setFilter(filter)
        self.model.select()


def main():
    app = QtWidgets.QApplication(sys.argv)
    db = QtSql.QSqlDatabase.addDatabase("QPSQL")  # !!! установите свое
    # db = psycopg2.connect(dbname='masl_tmp', user='postgres',
    #                     password='secret', host='192.168.251.xxx')
    db.setHostName("192.168.251.xxx")
    db.setPort(5432)
    db.setDatabaseName("masl_tmp")  # !!! установите свое
    db.setUserName("postgres")
    db.setPassword("secret")
    # cursor = db.cursor()

    # print(QtSql.QSqlDatabase.drivers())

    if not db.open():
        sys.exit(-1)

    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Пробовал подключиться через psycopg2. Все ок.


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

Автор решения: S. Nick

Один из возможных вариантов с использованием QTableView + QSqlTableModel выглядит так.

В этом случае следует использовать метод setFilter

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql                     # !!! установите свои импорты Pyside6


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.lineEdit = QtWidgets.QLineEdit()
        self.comboBox = QtWidgets.QComboBox()
        self.tableView = QtWidgets.QTableView()
        self.model = QtSql.QSqlTableModel()
        self.tableView.setModel(self.model)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.lineEdit, 0, 0)
        grid.addWidget(self.comboBox, 0, 1)
        grid.addWidget(self.tableView, 1, 0, 1, 2)

        self.model.setTable("students")                                # !!! установите свою таблицу
        self.model.select()

        self.comboBox.clear()
        for i in range(self.model.columnCount()):
            self.comboBox.addItem(self.model.headerData(i, QtCore.Qt.Horizontal))

        self.lineEdit.textChanged.connect(self.filter_table)

    def filter_table(self, text):
        filter = " {} LIKE '%{}%'".format(self.comboBox.currentText(), text) if text else text
        self.model.setFilter(filter)
        self.model.select()


def main():
    app = QtWidgets.QApplication(sys.argv)

    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")                   # !!! установите свое
    db.setDatabaseName("database.db")                                # !!! установите свое
    
    if not db.open():
        sys.exit(-1)

    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

введите сюда описание изображения

введите сюда описание изображения



Update

update 12.03.22 13:48 Изменил в предложенном S.Nick варианте подключение к БД. Но коннекта нет.

@MarcusStill, пожалуйста, вставьте все ваши водключения в мой пример и покажите весь код, который вы пробуете запускать.
И хорошо расскажите что у вас получается, что вы наблюдаете, какие ошибки вы получаету и.т.д.

Также попробуйте :

...
db.setHostName("localhost").
...

... 
self.model = QSqlTableModel(self.tableView, db)
table_name = 'units'                   # !!! установите свою таблицу  
self.model.setTable(table_name)
self.model.select()
...
→ Ссылка