PyQt5
64篇
PyQt5:PyQt5与数据库互联的小例子4(极简图书管理Plus)
导读:终篇
LEARN MORE
正文
这期是PyQt5与数据库互联小例子的最后一期,这期是完成主程序。
1
基础知识
本期我们将运用到两个类:QSqlDatabase类、QSqlQuery类。
QSqlDatabase类:主要用在数据库连接方面。
QSqlQuery类:主要用在数据库查询方面。
具体的介绍如下:
QSqlDatabase
QSqlDatabase类处理与数据库的连接。
QSqlDatabase类提供了通过连接访问数据库的接口。
QSqlDatabase的实例表示连接。该连接通过一个受支持的数据库驱动程序提供对数据库的访问,这些驱动程序源自QSqlDriver。
目前可用的数据支持类型如下:
通过调用其中一个静态addDatabase()函数创建连接(即QSqlDatabase的实例),您可以在其中指定要使用的驱动程序或驱动程序类型(取决于数据库的类型)和连接名称。
您可以与一个数据库建立多个连接。 QSqlDatabase还支持默认连接的概念,即未命名的连接。要创建默认连接,请在调用addDatabase()时不要传递连接名称参数。随后,如果在未指定连接名称的情况下调用任何静态成员函数,则将假定默认连接。以下代码段显示了如何创建和打开PostgreSQL数据库的默认连接:
创建QSqlDatabase对象后,使用setDatabaseName(),setUserName(),setPassword(),setHostName(),setPort()和setConnectOptions()设置连接参数。然后调用open()以激活与数据库的物理连接。在打开连接之前,该连接无法使用。
上面定义的连接将是默认连接,因为我们没有为addDatabase()提供连接名称。随后,您可以通过调用没有连接名称参数的database()来获取默认连接:
QSqlDatabase是一个值类。通过一个QSqlDatabase实例对数据库连接所做的更改将影响表示同一连接的其他QSqlDatabase实例。使用cloneDatabase()基于现有数据库连接创建独立的数据库连接。
强烈建议您不要将QSqlDatabase的副本作为类的成员保留,因为这会阻止在关闭时正确清除实例。如果需要访问现有的QSqlDatabase,则应使用database()访问它。如果您选择拥有QSqlDatabase成员变量,则需要在删除QCoreApplication实例之前将其删除,否则可能会导致未定义的行为。
如果创建多个数据库连接,请在调用addDatabase()时为每个连接指定唯一的连接名称。使用带有连接名称的database()来获取该连接。将removeDatabase()与连接名称一起使用以删除连接。如果尝试删除其他QSqlDatabase对象引用的连接,QSqlDatabase将输出警告。使用contains()查看给定的连接名称是否在连接列表中。
一些实用方法:
tables():返回表的列表
primaryIndex():返回表的主索引
record():返回有关表的字段的元信息
transaction():启动一个事务
commit():保存并完成事务
rollback():取消事务
hasFeature():检查驱动程序是否支持事务
lastError():返回有关上一个错误的信息
drivers():返回可用SQL驱动程序的名称
isDriverAvailable():检查特定驱动程序是否可用
registerSqlDriver():注册一个定制的驱动程序
注意:不推荐使用QSqlDatabase.exec()。 请改用QSqlQuery.exec()。
注意:使用事务时,必须在创建查询之前启动事务。
QSqlQuery
QSqlQuery类提供了一种执行和操作SQL语句的方法。
QSqlQuery封装了在QSqlDatabase上执行的SQL查询中创建,导航和检索数据所涉及的功能。它可用于执行DML(数据操作语言)语句,例如SELECT,INSERT,UPDATE和DELETE,以及DDL(数据定义语言)语句,例如CREATE TABLE。它还可以用于执行非标准SQL的特定于数据库的命令(例如,对于PostgreSQL,SET DATESTYLE = ISO)。
成功执行SQL语句将查询的状态设置为活动状态,以便isActive()返回True。否则,查询的状态将设置为非活动状态。在任何一种情况下,执行新的SQL语句时,查询都位于无效记录上。必须先将活动查询导航到有效记录(以便isValid()返回True),然后才能检索值。
对于某些数据库,如果在调用commit()或rollback()时存在作为SELECT语句的活动查询,则提交或回滚将失败。有关详细信息,请参阅isActive()。
使用以下功能执记录:
next():
检索结果中的下一条记录(如果可用),并将查询定位在检索到的记录上。 请注意,结果必须处于活动状态,并且isSelect()必须在调用此函数之前返回True,否则它将不执行任何操作并返回False。
以下规则适用:
如果结果当前位于第一条记录之前,在执行查询后立即尝试检索第一条记录。
如果结果当前位于最后一条记录之后,则没有更改,并返回False。
如果结果位于中间某处,则尝试检索下一条记录。
如果无法检索记录,则结果将定位在最后一条记录之后,并返回False。 如果成功检索到记录,则返回True。
previous():
检索结果中的上一条记录(如果可用),并将查询定位在检索到的记录上。 请注意,结果必须处于活动状态,并且isSelect()必须在调用此函数之前返回True,否则它将不执行任何操作并返回False。
以下规则适用:
如果结果当前位于第一条记录之前,则没有更改,并返回False。
如果结果当前位于最后一条记录之后,则尝试检索最后一条记录。
如果结果位于中间某处,则尝试检索先前的记录。
如果无法检索记录,则结果将位于第一个记录之前,并返回False。 如果成功检索到记录,则返回True。
first():
检索结果中的第一条记录(如果可用),并将查询定位在检索到的记录上。 请注意,结果必须处于活动状态,并且isSelect()必须在调用此函数之前返回True,否则它将不执行任何操作并返回False。 如果成功则返回True。 如果不成功,则将查询位置设置为无效位置并返回False。
last():
检索结果中的最后一条记录(如果可用),并将查询定位在检索到的记录上。 请注意,结果必须处于活动状态,并且isSelect()必须在调用此函数之前返回True,否则它将不执行任何操作并返回False。 如果成功则返回True。 如果不成功,则将查询位置设置为无效位置并返回False。
seek(index, relative = False):
检索位置索引处的记录(如果可用),并将查询定位在检索到的记录上。第一个记录位于位置0。请注意,查询必须处于活动状态,并且isSelect()必须在调用此函数之前返回True。
如果relative为False(默认值),则适用以下规则:
如果index为负数,则结果位于第一个记录之前,并返回False。否则,尝试移动到位置索引处的记录。如果无法检索位置索引处的记录,则结果将定位在最后一条记录之后,并返回False。如果成功检索到记录,则返回True。
如果relative为True,则适用以下规则:
如果结果当前位于第一条记录之前,则:
index为负数或零,没有变化,返回False。
index为正数,尝试将结果置于绝对位置index-1,遵循上述非相对搜索的相同规则。
如果结果当前位于最后一条记录之后,则:
index为正数或零,没有变化,返回False。
index为负,尝试按照以下规则将结果定位在距上一条记录的索引+ 1相对位置。
如果结果当前位于中间某处,并且相对偏移索引将结果移动到零以下,则结果将位于第一个记录之前,并返回False。
否则,尝试移动到当前记录之前的记录索引记录(如果索引为负,则转移到当前记录之后的索引记录)。如果无法检索偏移索引处的记录,则结果将定位在最后一条记录之后,如果index> = 0,(或者在第一条记录之前,如果索引为负数),则返回False。如果成功检索到记录,则返回True。
这些函数允许程序员通过查询返回的记录向前,向后或任意移动。 如果您只需要继续查看结果(例如,使用next()),则可以使用setForwardOnly(),这将节省大量内存开销并提高某些数据库的性能。 将活动查询定位在有效记录上后,可以使用value()检索数据。 使用QVariants从SQL后端传输所有数据。
例如:
要访问查询返回的数据,请使用value(int)。 SELECT语句返回的数据中的每个字段都是通过从0开始在语句中传递字段的位置来访问的。这使得使用SELECT *查询是不可取的,因为返回的字段的顺序是不确定的。
为了提高效率,没有按名称访问字段的功能(除非您使用带有名称的预准备查询,如下所述)。要将字段名称转换为索引,请使用record()。indexOf(),例如:
2
核心代码讲解
我们首先要连接数据库,addDatabase()使用驱动程序类型和连接名称connectionName(这里是”QSQLITE”)将数据库添加到数据库连接列表中。如果已存在名为connectionName的数据库连接,则删除该连接。
设置数据库名称,并调用open()打开,我们会看看是否打开成功?成功返回db,数据库连接对象;否则返回False。
对数据库以及数据模型进行一些设置。
设置要显示的视图的模型,这里的模型就是在
《PyQt5:PyQt5与数据库互联的小例子2(极简图书管理Plus)》
里面提到自定义数据模型
设置数据库中的值编辑策略。这里有三种,如下表:
将模型操作的数据库表设置为tableName。 不从表中选择数据,而是获取其字段信息。
要使用表的数据填充模型,请调用select()。可以使用lastError()检索错误信息。
设置表头内容,没有这几句是这样的:
隐藏一些我不想显示的字段,如:图书封面的路径。没有这几句效果如下:
右键菜单,单击后直接连接到deleterows()函数。
这两个函数的主要目的是取得我们要删除的行,然后再加以删除。
返回所有选定模型项索引的列表。
我们根据返回的索引列表,去重一下,取得相应的行号。大家可以看一下,如果我们选择一整行,如下图这种:
会有很多重复的行号。为什么会这样呢?因为一行里面有很多的QModelIndex对象组成的列表,这些QModelIndex对象的行号都是一样的。
单击显示图书详细信息。
当我们单击表格的时候,取得行号。
因为我们的数据来源都是数据模型,我们就根据模型中第几行第几个字段取得相应的值,如下,下图表示的是第3行(0行开始)”subtitle”的内容。
这里的重点语句就是:
设置要过滤的当前过滤器。过滤器是不带关键字WHERE的SQL WHERE子句(例如,name =’Josephine’)。
如果模型已填充了数据库中的数据,则模型将使用新过滤器重新选择它。 否则,将在下次调用select()时应用过滤器。
如:
就表示类似如下的SQL语句:
3
最后
好的,关于PyQt5与数据库互联的介绍就到这里了。如果你喜欢本篇文章,请给我点赞
赞赏(推荐)
分享给你的好友们吧!
领取专属 10元无门槛券
私享最新 技术干货