Qt中提供了3个用于访问数据库更高级别的类,分别为QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。
QSqlQueryModel是查询模型,通过查询函数setQuery('sql语句')来实现数据库查询功能,这个模型属于只读性查询。
QSqlTableModel是单表读/写模型,使用setTable('表名')函数,检查一个表,可以实现读/写,并可以使用setFilter()进行条件筛选,使用setSort()函数进行排序,使用select()函数执行数据检索。是相比QSqlQueryModel高级的替代方案,用于导航和修改单个表数据。并且可以使用策略,数据发生变化立即生效(自动提交)
model.setEditStrategy(QSqlTableModel.EditStrategy.OnRowChange)
QSqlRelationalTableModel是扩展了QSqlTableModel,提供对外键的支持,使用setTalbe()函数检索一个表,使用setRelation()连接外键关联其它表的相关字段。
比如,有一个Sqlite3数据库database.db文件,该数据库有一个student表,student表中两个字段sex和subject 分别关联两位sex表的id字段,关联subject表的id字段,如下:
dbConn = QSqlDatabase.addDatabase('QSQLITE')
dbConn.setDatabaseName('./db/database.db')
self.model = QSqlRelationalTableModel(db=dbConn)
self.model.setTable("student2")
self.sexIndex = self.model.fieldIndex('sex')
self.subjectIndex = self.model.fieldIndex('subject')
self.model.setRelation(self.sexIndex, QSqlRelation("sex", "id", "name"))
self.model.setRelation(self.subjectIndex, QSqlRelation("subject", "id", "name"))
self.model.select()
特别注意的是,上面代码出现错误,系统并不会立即报错,比如数据中没有student表,或者sex表,上面代码不会报错,而且执行select()也没有提醒。系统在运行视图绑定模型,视图数据时才会发生报错,运行代码会提示在视图绑定模型的代码语句。
对于上面问题,通常在尝试执行数据库操作之后检查模型的状态或执行查询之前检查表是否存在。一种方式是使用QSqlError
来检查在数据库操作过程中是否发生了错误。在上面代码后,加下面代码:
if self.model.lastError().isValid(): # 检查是否有错误发生
QMessageBox.critical(None, '警告', '表不存在或发生其他错误: {}'.format(self.model.lastError().text()))
exit()
另外,如果程序仅有一个数据库连接,创建模型实例,不用任何参数即可。如下:
dbConn = QSqlDatabase.addDatabase('QSQLITE')
dbConn.setDatabaseName('./db/database.db')
# 上面语句会创建数据库连接,并设定为默认的数据库连接
# 下面语句建立模型实例对象,不用参数,系统会选择默认的数据库连接
self.model = QSqlRelationalTableModel()
# 显示指定也是很好的选择
self.model = QSqlRelationalTableModel(db = dbConn)