当前位置:   article > 正文

Hello PyQt5(八)PyQt5数据库操作_pyqt连接数据库

pyqt连接数据库

一、SQLite数据库 

1、SQLite简介

SQLite是一个轻量级的数据库,实现了自给自足、无服务器、零配置、事务性的SQL数据库引擎,主要作为手机应用的数据库以及小型桌面应用的数据库。

官方网站:

SQLite Home Page

2、SQLite常用操作

创建数据库文件,创建后进行入SQLite命令行模式。

sqlite3 DatabaseName.db

查看已经存在的数据库文件,在SQLite命令行模式执行:

.databases

打开已经存在的数据库文件,如果数据库文件不存在,则创建。

sqlite3 DatabaseName.db

查看帮助信息,在SQLite命令行模式执行:

.help

创建表,在SQLite命令行模式执行:

create table person(id integer primary key, name text);

插入数据到表:

insert into person(id, name) values(1, "zhangsan");

查询操作:

select * from person;

查询表的结构:

.schema person

3、SQLite管理工具

SQLite有多个开源且优秀的DBMS(数据库管理系统),提供了界面操作SQLite数据库。

SQLiteStudio是一款非常专业的SQLite数据库管理软件,体积小巧,功能强大,支持中文,免安装。

SQLiteStudio下载:

https://sqlitestudio.pl/index.rvt?act=download

二、连接数据库

1、数据库驱动类型

PyQt中,QSqlDatabase类用于连接数据库,可以使用数据库驱动与不同的数据库进行交互,一个QSqlDatabase实例代表一次数据库连接。可用数据库驱动类型如下:

QDB2 IBM DB2驱动程序

QMYSQL MySQL驱动程序

QOCI Oracle调用接口驱动程序

QODBC ODBC驱动程序(包括MS SQL Server)

QPSQL PostgreSQL驱动程序

QSQLITE SQLite3驱动程序

QSQLITE2 SQLite2驱动程序

2、QSqlDatabase常用方法

QSqlDatabase常用方法如下:

addDataBase:设置连接数据库的数据库驱动类型

setDatabaseName:设置所连接的数据库名称

setHostName:设置数据库所在的主机名称

setUserName:指定连接的用户名

setPassword:设置连接对象的密码

commit:提交事务,如果执行成功返回True。

rollback:回滚数据库事务

close:关闭数据库连接

3、数据库连接实例

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase
  3. from PyQt5.QtCore import *
  4. if __name__ == "__main__":
  5.     app = QCoreApplication(sys.argv)
  6.     db = QSqlDatabase.addDatabase("QSQLITE")
  7.     db.setDatabaseName("/home/user/test.db")
  8.     if db.open():
  9.         print("open DB success.")
  10.     sys.exit(app.exec_())

三、执行SQL语句

QSqlQuery具有执行和操作SQL语句的功能,可以执行DDL和DML类型的SQL查询,QSqlQuery.exec_()用于执行SQL操作。

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase, QSqlQuery
  3. from PyQt5.QtCore import *
  4. def createDB():
  5.     db = QSqlDatabase.addDatabase("QSQLITE")
  6.     db.setDatabaseName("/home/user/test.db")
  7.     if db.open():
  8.         query = QSqlQuery()
  9.         query.exec_("create table person(id int primary key, name varchar(20), address varchar(30))")
  10.         query.exec_("insert into person values(1, 'Bauer', 'beijing')")
  11.         query.exec_("insert into person values(2, 'Jack', 'shanghai')")
  12.         query.exec_("insert into person values(3, 'Alex', 'chengdu')")
  13.         db.close()
  14. if __name__ == "__main__":
  15.     app = QCoreApplication(sys.argv)
  16.     createDB()
  17.     sys.exit(app.exec_())

执行完SQL语句后,如果没有其它数据库操作,需要使用db.close关闭数据库连接,因为数据库连接资源是有限的,不再使用的数据库连接必须关闭,否则数据库连接资源最终会被耗尽,导致程序无法正常连接数据库。

如果在PyQt的窗口中需要读取数据库的数据并进行显示,则需要在窗口初始化时打开数据库,在窗口关闭时关闭数据库连接。

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase, QSqlQuery
  3. from PyQt5.QtCore import *
  4. from PyQt5.QtWidgets import *
  5. class MainWindow(QWidget):
  6.     def __init__(self, parent=None):
  7.         super(MainWindow, self).__init__(parent)
  8.         self.db = QSqlDatabase.addDatabase("QSQLITE")
  9.         self.db.setDatabaseName("/home/user/test.db")
  10.         self.db.open()
  11.     def closeEvent(self, event):
  12.         self.db.close()
  13. if __name__ == "__main__":
  14.     app = QApplication(sys.argv)
  15.     window = MainWindow()
  16.     window.show()
  17.     sys.exit(app.exec_())

四、数据库模型视图

Qt中的QSqlTableModel是一个高级接口,提供了可读可写的数据模型,用于在单个表中读取和保存数据,可以在QTableView展示数据库的表格。当连接到数据库后,使用seTable设置要查询的表,使用setFilter函数设置过滤器条件,然后使用select函数进行查询操作。可以使用setEditerStrategy函数设置编辑策略,可设置编辑策略如下:

QSqlTableModel.OnFieldChange:所有变更实时更新到数据库

QSqlTableModel.OnRowChange:当用户选择不同的行时,在当前行进行更新

QSqlTableModel.OnManuallSubmit:手动提交,不自动提交

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
  3. from PyQt5.QtCore import *
  4. from PyQt5.QtWidgets import *
  5. class MainWindow(QWidget):
  6.     def __init__(self, parent=None):
  7.         super(MainWindow, self).__init__(parent)
  8.         self.db = QSqlDatabase.addDatabase("QSQLITE")
  9.         self.db.setDatabaseName("/home/user/test.db")
  10.         self.db.open()
  11.         self.model = QSqlTableModel()
  12.         self.initializedModel()
  13.         self.tableView = QTableView()
  14.         self.tableView.setModel(self.model)
  15.         self.layout = QVBoxLayout()
  16.         addButton = QPushButton("add")
  17.         deleteButton = QPushButton("delete")
  18.         hLayout = QHBoxLayout()
  19.         hLayout.addWidget(addButton)
  20.         hLayout.addWidget(deleteButton)
  21.         self.layout.addWidget(self.tableView)
  22.         self.layout.addLayout(hLayout)
  23.         self.setLayout(self.layout)
  24.         self.resize(600, 400)
  25.         addButton.clicked.connect(self.onAddRow)
  26.         deleteButton.clicked.connect(self.onDeleteRow)
  27.     def initializedModel(self):
  28.         self.model.setTable("person")
  29.         self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
  30.         self.model.select()
  31.         self.model.setHeaderData(0, Qt.Horizontal, "ID")
  32.         self.model.setHeaderData(1, Qt.Horizontal, "Name")
  33.         self.model.setHeaderData(2, Qt.Horizontal, "Address")
  34.     def onAddRow(self):
  35.         self.model.insertRows(self.model.rowCount(), 1)
  36.         self.model.submit()
  37.     def onDeleteRow(self):
  38.         self.model.removeRow(self.tableView.currentIndex().row())
  39.         self.model.submit()
  40.         self.model.select()
  41.     def closeEvent(self, event):
  42.         self.db.close()
  43. if __name__ == "__main__":
  44.     app = QApplication(sys.argv)
  45.     window = MainWindow()
  46.     window.show()
  47.     sys.exit(app.exec_())

五、分页查询

1、数据准备

分页使用数据为学生信息student表,可以使用SQLite命令行使用SQL语句插入,也可以使用Python程序创建表并插入数据。

  1. db = QSqlDatabase.addDatabase("QSQLITE")
  2. db.setDatabaseName("/home/user/test.db")
  3. if not db.open():
  4.     return False
  5. query = QSqlQuery()
  6. query.exec_("create table student(id int primary key, name varchar(20), sex varchar(8), age int);")
  7. query.exec_("insert into student values(1, 'Bauer', 'Man', 25)")
  8. query.exec_("insert into student values(2, 'Alex', 'Man', 24)")
  9. query.exec_("insert into student values(3, 'Mary', 'Female', 23)")
  10. query.exec_("insert into student values(4, 'Jack', 'Man', 25)")
  11. query.exec_("insert into student values(5, 'xiaoming', 'Man', 24)")
  12. query.exec_("insert into student values(6, 'xiaohong', 'Female', 23)")
  13. query.exec_("insert into student values(7, 'xiaowang', 'Man', 25)")
  14. query.exec_("insert into student values(8, 'xiaozhang', 'Man', 25)")
  15. query.exec_("insert into student values(9, 'xiaoli', 'Man', 25)")
  16. query.exec_("insert into student values(10, 'xiaohan', 'Man', 25)")

2、分页窗口

分页窗口包括标签、前一页、后一页、跳转按钮等。

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
  3. from PyQt5.QtCore import *
  4. from PyQt5.QtWidgets import *
  5. class DataGrid(QWidget):
  6.     def __init__(self, parent=None):
  7.         super(DataGrid, self).__init__(parent)
  8.         # 数据库连接
  9.         self.db = None
  10.         # 布局管理器
  11.         self.layout = QVBoxLayout()
  12.         # 查询模型
  13.         self.queryModel = QSqlQueryModel()
  14.         # 表格视图
  15.         self.tableView = QTableView()
  16.         self.tableView.setModel(self.queryModel)
  17.         #
  18.         self.totalPageLabel = QLabel()
  19.         self.currentPageLabel = QLabel()
  20.         self.switchPageLineEdit = QLineEdit()
  21.         self.prevButton = QPushButton("Prev")
  22.         self.nextButton = QPushButton("Next")
  23.         self.switchPageButton = QPushButton("Switch")
  24.         self.currentPage = 0
  25.         self.totalPage = 0
  26.         self.totalRecordCount = 0
  27.         self.pageRecordCount = 5
  28.     def initUI(self):
  29.         self.tableView.horizontalHeader().setStretchLastSection(True)
  30.         self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  31.         self.layout.addWidget(self.tableView)
  32.         hLayout = QHBoxLayout()
  33.         hLayout.addWidget(self.prevButton)
  34.         hLayout.addWidget(self.nextButton)
  35.         hLayout.addWidget(QLabel("跳转到"))
  36.         self.switchPageLineEdit.setFixedWidth(40)
  37.         hLayout.addWidget(self.switchPageLineEdit)
  38.         hLayout.addWidget(QLabel("页"))
  39.         hLayout.addWidget(self.switchPageButton)
  40.         hLayout.addWidget(QLabel("当前页:"))
  41.         hLayout.addWidget(self.currentPageLabel)
  42.         hLayout.addWidget(QLabel("总页数:"))
  43.         hLayout.addWidget(self.totalPageLabel)
  44.         hLayout.addStretch(1)
  45.         self.layout.addLayout(hLayout)
  46.         self.setLayout(self.layout)
  47.         self.setWindowTitle("DataGrid")
  48.         self.resize(600, 300)
  49.     def closeEvent(self, event):
  50.         self.db.close()
  51. if __name__ == "__main__":
  52.     app = QApplication(sys.argv)
  53.     window = DataGrid()
  54.     window.initUI()
  55.     window.show()
  56.     sys.exit(app.exec_())

 3、分页查询实现

读取数据库的student表,初始化表格数据模型。

  1. import sys
  2. from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
  3. from PyQt5.QtCore import *
  4. from PyQt5.QtWidgets import *
  5. import re
  6. class DataGrid(QWidget):
  7.     def __init__(self, parent=None):
  8.         super(DataGrid, self).__init__(parent)
  9.         # 声明数据库连接
  10.         self.db = None
  11.         # 布局管理器
  12.         self.layout = QVBoxLayout()
  13.         # 查询模型
  14.         self.queryModel = QSqlQueryModel()
  15.         # 表格视图
  16.         self.tableView = QTableView()
  17.         self.tableView.setModel(self.queryModel)
  18.         #
  19.         self.totalPageLabel = QLabel()
  20.         self.currentPageLabel = QLabel()
  21.         self.switchPageLineEdit = QLineEdit()
  22.         self.prevButton = QPushButton("Prev")
  23.         self.nextButton = QPushButton("Next")
  24.         self.switchPageButton = QPushButton("Switch")
  25.         # 当前页
  26.         self.currentPage = 1
  27.         # 总页数
  28.         self.totalPage = None
  29.         # 总记录数
  30.         self.totalRecordCount = None
  31.         # 每页记录数
  32.         self.pageRecordCount = 4
  33.         self.initUI()
  34.         self.initializedModel()
  35.         self.setUpConnect()
  36.         self.updateStatus()
  37.     def initUI(self):
  38.         self.tableView.horizontalHeader().setStretchLastSection(True)
  39.         self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  40.         self.layout.addWidget(self.tableView)
  41.         hLayout = QHBoxLayout()
  42.         hLayout.addWidget(self.prevButton)
  43.         hLayout.addWidget(self.nextButton)
  44.         hLayout.addWidget(QLabel("跳转到"))
  45.         self.switchPageLineEdit.setFixedWidth(40)
  46.         hLayout.addWidget(self.switchPageLineEdit)
  47.         hLayout.addWidget(QLabel("页"))
  48.         hLayout.addWidget(self.switchPageButton)
  49.         hLayout.addWidget(QLabel("当前页:"))
  50.         hLayout.addWidget(self.currentPageLabel)
  51.         hLayout.addWidget(QLabel("总页数:"))
  52.         hLayout.addWidget(self.totalPageLabel)
  53.         hLayout.addStretch(1)
  54.         self.layout.addLayout(hLayout)
  55.         self.setLayout(self.layout)
  56.         self.setWindowTitle("DataGrid")
  57.         self.resize(600, 300)
  58.     def setUpConnect(self):
  59.         self.prevButton.clicked.connect(self.onPrevPage)
  60.         self.nextButton.clicked.connect(self.onNextPage)
  61.         self.switchPageButton.clicked.connect(self.onSwitchPage)
  62.     def initializedModel(self):
  63.         self.db = QSqlDatabase.addDatabase("QSQLITE")
  64.         self.db.setDatabaseName("/home/user/test.db")
  65.         if not self.db.open():
  66.             return False
  67.         self.queryModel.setHeaderData(0, Qt.Horizontal, "ID")
  68.         self.queryModel.setHeaderData(1, Qt.Horizontal, "Name")
  69.         self.queryModel.setHeaderData(2, Qt.Horizontal, "Sex")
  70.         self.queryModel.setHeaderData(3, Qt.Horizontal, "Age")
  71.         # 获取表的所有记录数
  72.         sql = "SELECT * FROM student"
  73.         self.queryModel.setQuery(sql, self.db)
  74.         self.totalRecordCount = self.queryModel.rowCount()
  75.         if self.totalRecordCount % self.pageRecordCount == 0:
  76.             self.totalPage = self.totalRecordCount / self.pageRecordCount
  77.         else:
  78.             self.totalPage = int(self.totalRecordCount / self.pageRecordCount) + 1
  79.         # 显示第1页
  80.         sql = "SELECT * FROM student limit %d,%d" % (0, self.pageRecordCount)
  81.         self.queryModel.setQuery(sql, self.db)
  82.     def onPrevPage(self):
  83.         self.currentPage -= 1
  84.         limitIndex = (self.currentPage - 1) * self.pageRecordCount
  85.         self.queryRecord(limitIndex)
  86.         self.updateStatus()
  87.     def onNextPage(self):
  88.         self.currentPage += 1
  89.         limitIndex = (self.currentPage - 1) * self.pageRecordCount
  90.         self.queryRecord(limitIndex)
  91.         self.updateStatus()
  92.     def onSwitchPage(self):
  93.         szText = self.switchPageLineEdit.text()
  94.         pattern = re.compile('^[0-9]+$')
  95.         match = pattern.match(szText)
  96.         if not match:
  97.             QMessageBox.information(self, "提示", "请输入数字.")
  98.             return
  99.         if szText == "":
  100.             QMessageBox.information(self, "提示", "请输入跳转页面.")
  101.             return
  102.         pageIndex = int(szText)
  103.         if pageIndex > self.totalPage or pageIndex < 1:
  104.             QMessageBox.information(self, "提示", "没有指定的页,清重新输入.")
  105.             return
  106.         limitIndex = (pageIndex - 1) * self.pageRecordCount
  107.         self.queryRecord(limitIndex)
  108.         self.currentPage = pageIndex
  109.         self.updateStatus()
  110.     # 根据分页查询记录
  111.     def queryRecord(self, limitIndex):
  112.         sql = "SELECT * FROM student limit %d,%d" % (limitIndex, self.pageRecordCount)
  113.         self.queryModel.setQuery(sql)
  114.     # 更新空间状态
  115.     def updateStatus(self):
  116.         self.currentPageLabel.setText(str(self.currentPage))
  117.         self.totalPageLabel.setText(str(self.totalPage))
  118.         if self.currentPage <= 1:
  119.             self.prevButton.setEnabled(False)
  120.         else:
  121.             self.prevButton.setEnabled(True)
  122.         if self.currentPage >= self.totalPage:
  123.             self.nextButton.setEnabled(False)
  124.         else:
  125.             self.nextButton.setEnabled(True)
  126.     # 界面关闭时关闭数据库连接
  127.     def closeEvent(self, event):
  128.         self.db.close()
  129. if __name__ == "__main__":
  130.     app = QApplication(sys.argv)
  131.     window = DataGrid()
  132.     window.show()
  133.     sys.exit(app.exec_())

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/264599
推荐阅读
相关标签
  

闽ICP备14008679号