使用 PySide 获取一个或多个连接表中的值

Get values in one or more joined tables using PySide

我试图了解在处理通过唯一 ID 链接的表时使用 QSqlRelationalTableModel 与 QSqlTableModel 的优势。在以下示例中,组织字段按名称而不是 ID 号正确显示。但是,如何访问链接记录的相应 "size" 或 "address" 字段?

from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtSql import *

db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("relational_test_01.sqlite")
db.open()
q = QSqlQuery()
q.exec_("CREATE TABLE people(id INTEGER PRIMARY KEY, first VARCHAR(50), last VARCHAR(50), organization INTEGER)")
q.exec_("INSERT INTO people VALUES(1,'John', 'Smith', 1)")
q.exec_("INSERT INTO people VALUES(2,'Bob', 'Jones', 2)")
q.exec_("CREATE TABLE organizations(id INTEGER PRIMARY KEY, name VARCHAR(50),  size INTEGER, address VARCHAR(50))")
q.exec_("INSERT INTO organizations VALUES(1,'Central Gym', 30, '400 Central Street')")
q.exec_("INSERT INTO organizations VALUES(2,'Shoe Store', 5, '200 Central Street')")

db.close()


model = QSqlRelationalTableModel()
model.setTable("people")
model.setRelation(3, QSqlRelation("organizations", "id", "name"))
model.setFilter("people.id = 1")
model.select()
count = model.rowCount()
if count == 1:
    record = model.record(0)
    org = record.value(3)
    print(org)

此处缺少一项功能,已报告为 QTBUG-9320。具体来说,没有明显的方法可以从相关的 table.

中获取原始外键值

幸运的是,有一个未记录的解决方法可以避免该问题。这是通过利用 QSqlRelation 的第三个参数来实现的,它实际上能够在结果中指定多个列。

以下是如何在您的示例中使用它:

model = QSqlRelationalTableModel()
model.setTable("people")
model.setRelation(3, QSqlRelation("organizations", "id", "name, relTblAl_3.id"))
model.setFilter("people.id = 1")
model.select()
record = model.record(0)
for i in range(record.count()):
    print((i, record.value(i)))
org_model = model.relationModel(3)
org_model.setFilter('organizations.id = %s' % record.value(4))
org_model.select()
record = org_model.record(0)
print()
for i in range(record.count()):
    print((i, record.value(i)))

输出:

(0, 1)
(1, 'John')
(2, 'Smith')
(3, 'Central Gym')
(4, 1)

(0, 1)
(1, 'Central Gym')
(2, 30)
(3, '400 Central Street')

需要 relTblAl_3.id 以避免名称冲突,并记录在 Detailed Description for QSqlRelationalTableModel 末尾的注释中。但是,如果您始终为每一列使用唯一的名称,则可以避免这种情况(例如,使用 org_id 而不是 id 则不需要使用 table 名称进行限定)。