Как вывести результат запроса из БД в 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 шт):
Один из возможных вариантов с использованием 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()
...

