从 SQLAlchemy 填充 QTableView

Populate a QTableView from SQLAlchemy

我正在尝试使用 PyQt5 和 SQLAlchemy 作为 orm 创建一些小型 GUI 应用程序,但是,我似乎找不到从 SQLAlchemy 查询填充 QTableView 的方法。

我的目标是使用 SQLAlchemy 检索数据,然后在 QTableView 中显示查询结果。

我可以使用以下代码获取数据:

def fetch_data():
    metadata = db.schema.MetaData(bind=engine, reflect=True)
    table = db.Table('tbl_inv', metadata, autoload=True)

    query = db.select([
         table.columns.code,
         table.columns.decription,
         table.columns.uom,
    ])

    result = conn.execute(query)
    result_set = result.fetchall()

    return result_set

我正在尝试实现它,但没有成功。 .

我想我必须将我的数据放入数据框然后使用上面的链接解决方案,但我确信这在操作方面会很昂贵。

程序步骤

  1. 设置环境
sudo apt install python3-pip
sudo pip3 install pyqt5
sudo pip3 install sqlalchemy
  1. 运行 demo.py(会在本地插入测试数据到sqlite)
from PyQt5.QtWidgets import QApplication, QWidget, QTableView, QAbstractItemView, QVBoxLayout
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtGui, QtCore
import sqlalchemy as db
import os

# 1. rm demo.db
os.remove("demo.db")

engine = db.create_engine('sqlite:///demo.db?check_same_thread=False', echo=True)
# 2. Creates demo table
connection = engine.connect()
metadata = db.MetaData()
demoTable = db.Table('demo', metadata,
            db.Column('code', db.String(255), nullable=False),
            db.Column('decription', db.String(255), nullable=False),
            db.Column('uom', db.String(255), nullable=False)
            )

metadata.create_all(engine) 

# 3. Creates demo data
query = db.insert(demoTable) 
values_list = [
    {'code':'058176', 'decription':'01', 'uom':'rb1705,rb1710'},
    {'code':'058176', 'decription':'02', 'uom':'cu1705,cu1710'},
    {'code':'058176', 'decription':'03', 'uom':'zn1705,zn1710'},
    {'code':'058176', 'decription':'04', 'uom':'rb1705,rb1710'},
    {'code':'058176', 'decription':'01', 'uom':'zn1705,zn1710'},
    {'code':'058176', 'decription':'02', 'uom':'ru1705,ru1710'},
    {'code':'058176', 'decription':'02', 'uom':'ni1705,ni1710'},
    {'code':'058176', 'decription':'01', 'uom':'rb1705,rb1710'},
]
ResultProxy = connection.execute(query,values_list)

class DemoWindow(QWidget):
    def __init__(self, header, *args):
        QWidget.__init__(self, *args)
        self.setWindowTitle("Demo QTableView")

        self.table_model = DemoTableModel(self, header)
        self.table_view = QTableView()
        self.table_view.setModel(self.table_model)
        layout = QVBoxLayout(self)
        layout.addWidget(self.table_view)
        self.setLayout(layout)

class DemoTableModel(QAbstractTableModel):

    def __init__(self, parent, header, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        # 5. fetch data
        results = connection.execute(db.select([demoTable])).fetchall()
        self.mylist = results
        self.header = header

    def rowCount(self, parent):
        return len(self.mylist)

    def columnCount(self, parent):
        return len(self.mylist[0])

    def data(self, index, role):
        # 5. populate data
        if not index.isValid():
            return None
        if (role == Qt.DisplayRole):
            return self.mylist[index.row()][index.column()]
        else:
            return QVariant()

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[col]
        return None

if __name__ == '__main__':
    app = QApplication([])
    header = ['code', 'decription', 'uom']
    win = DemoWindow(header)
    win.show()
    app.exec_()