使用 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 名称进行限定)。
我试图了解在处理通过唯一 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 名称进行限定)。