赞
踩
什么是SQLite
SQLite是一个轻量级的数据库,实现了自给自足、无服务器、零配置、事务性的 SOL 数据库引擎,其部署最广泛。SQLite 源代码不受版权限制。
安装并使用SQLite
配置环境变量
安装完成
SQLite常用操作
新建数据库
查看已建立的数据库文件
打开已建立的数据库文件
若数据库文件不存在,则会自动新建数据库文件
查看帮助信息
创建表
create table people(id integer primary key,name text);
插入数据
查询
开启表头
查看表结构
使用SQLite管理工具
这里笔者使用Navicat 15
PyQt APl 经过精心设计,提供了很多基于SQL 的数据库通信类。其中QSqIDatabase类用来连接数据库,可以使用数据库驱动(Driver)与不同的数据库进行交互。一个OSqlDatabase实例代表了一次数据库连接。
数据库驱动类型:
数据库驱动类型 | 描述 |
---|---|
QDB2 | IBM DB2驱动程序 |
QIBASE | Borland InterBase驱动程序 |
QMYSQL | MySQL驱动程序 |
QOCI | Oracle调用接口驱动程序 |
QODBC | ODBC驱动程序(包含Microsoft SQL Server) |
QPSQL | PostgreSQL驱动程序 |
QSQLITE | SQLite3或更高版本的驱动程序 |
QSQLITE2 | SQLite2驱动程序 |
QSqlDatabase类中的常用方法
方法 | 描述 |
---|---|
addDatabase() | 设置连接数据库的数据库驱动类型 |
setDatabaseName() | 设置所连接的数据库名称 |
setHostName() | 设置安装数据库的主机名称 |
setUserName() | 指定连接的用户名 |
setPassword() | 设置连接对象的密码(如果有) |
commit() | 提交事务,如果执行成功则返回True |
rollback() | 回滚数据库事务 |
close() | 关闭数据库连接 |
案例——使用QSqlDatabase连接MySQL数据库、SQLite数据库
from PyQt5.QtSql import QSqlDatabase
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("127.0.0.1")
db.setDatabaseName("pyqt")
db.setUserName("root")
db.setPassword("200039")
dbConn = db.open()
连接到SQLite数据库
from PyQt5.QtSql import QSqlDatabase
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('E:\\SQLiteDatabases\\testDb.db')
dbConn = db.open()
QSqlQuery类具有执行和操作SQL语句的功能,可以执行 DDL 和 DML类型的SQL查询。
该类中最重要的方法是exec_(),它将一个包含要执行的SQL语句的字符串作为参数。
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtSql import QSqlDatabase , QSqlQuery def createDB(): db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('db/database.db') if not db.open(): QMessageBox.critical(None , ("无法打开数据库"),("无法建立连接,单击取消退出"), QMessageBox.Cancel) return False query = QSqlQuery() query.exec_("create table people(id int primary key ,name varchar(20) ,address varchar(30))") query.exec_("insert into people values (1,'zhangsan1','BeiJing')") query.exec_("insert into people values (2,'lisi1','TianJin')") query.exec_("insert into people values (3,'wangwu1','HeNan')") query.exec_("insert into people values (4,'lisi2','HeBei')") query.exec_("insert into people values (5,'wangwu2','ShangHai')") # 关闭数据库 db.close() return True if __name__ == '__main__': app = QApplication(sys.argv) createDB() sys.exit(app.exec_())
成功连接并处理
PyQt中的 QSqITableModel类是一个高级接口,提供了可读的数据模型,用在单个表中读取和保存数据。此模型用于填充QTableView对象,它向用户呈现了可以放在任何顶层窗口中的可滚动和可编辑的视图。
QSqITableModel类是一个可以读和写的表格模型,当连接到数据库后,使用setTable()函数设置要查询的表,使用setFilter()函数设置过滤器条件,这个过滤器条件与SQL查询语句中的where条件一样,然后使用select()函数执行查询,最后使用setEditStrategy()函数设置“编辑策略”。
可设置的编辑策略:
编辑策略 | 描述 |
---|---|
QSqlTableModel.OnFieldChange | 所有变更实时更新到数据库中 |
QSqlTableModel.OnRowChange | 当用户选择不同的行时,在当前行进行更改 |
QSqlTableModel.OnManualSubmit | 手动提交,不自动提交 |
案例
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtSql import QSqlDatabase, QSqlTableModel from PyQt5.QtCore import Qt def initializeModel(model): model.setTable('people') model.setEditStrategy(QSqlTableModel.OnFieldChange) model.select() model.setHeaderData(0, Qt.Horizontal, "ID") model.setHeaderData(1, Qt.Horizontal, "name") model.setHeaderData(2, Qt.Horizontal, "address") def createView(title, model): view = QTableView() view.setModel(model) view.setWindowTitle(title) return view def addrow(): ret = model.insertRows(model.rowCount(), 1) print('insertRows=%s' % str(ret)) def findrow(i): delrow = i.row() print('del row=%s' % str(delrow)) if __name__ == '__main__': app = QApplication(sys.argv) db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('db/database.db') model = QSqlTableModel() delrow = -1 initializeModel(model) view1 = createView("Table Model (View 1)", model) view1.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view1) addBtn = QPushButton("添加一行") addBtn.clicked.connect(addrow) layout.addWidget(addBtn) delBtn = QPushButton("删除一行") delBtn.clicked.connect(lambda: model.removeRow(view1.currentIndex().row())) layout.addWidget(delBtn) dlg.setLayout(layout) dlg.setWindowTitle("Database 例子") dlg.resize(430, 450) dlg.show() sys.exit(app.exec_())
准备分页数据
CREATE TABLE "student" ( "id" int, "name" vchar, "sex" vchar, "age" int, "deparment" vchar, PRIMARY KEY ("id") ); INSERT INTO "student" VALUES (1, '张三1', '男', 20, '计算机'); INSERT INTO "student" VALUES (2, '李四1', '男', 19, '经管'); INSERT INTO "student" VALUES (3, '王五1', '男', 22, '机械'); INSERT INTO "student" VALUES (4, '赵六1', '男', 21, '法律'); INSERT INTO "student" VALUES (5, '小明1', '男', 20, '英语'); INSERT INTO "student" VALUES (6, '小李1', '女', 19, '计算机'); INSERT INTO "student" VALUES (7, '小张1', '男', 20, '机械'); INSERT INTO "student" VALUES (8, '小刚1', '男', 19, '经管'); INSERT INTO "student" VALUES (9, '张三2', '男', 21, '计算机'); INSERT INTO "student" VALUES (10, '张三3', '女', 20, '法律'); INSERT INTO "student" VALUES (11, '王五2', '男', 19, '经管'); INSERT INTO "student" VALUES (12, '张三4', '男', 20, '计算机'); INSERT INTO "student" VALUES (13, '小李2', '男', 20, '机械'); INSERT INTO "student" VALUES (14, '李四2', '女', 19, '经管'); INSERT INTO "student" VALUES (15, '赵六3', '男', 21, '英语'); INSERT INTO "student" VALUES (16, '李四2', '男', 19, '法律'); INSERT INTO "student" VALUES (17, '小张2', '女', 22, '经管'); INSERT INTO "student" VALUES (18, '李四3', '男', 21, '英语'); INSERT INTO "student" VALUES (19, '小李3', '女', 19, '法律'); INSERT INTO "student" VALUES (20, '王五3', '女', 20, '机械'); INSERT INTO "student" VALUES (21, '张三4', '男', 22, '计算机'); INSERT INTO "student" VALUES (22, '小李2', '男', 20, '法律'); INSERT INTO "student" VALUES (23, '张三5', '男', 19, '经管'); INSERT INTO "student" VALUES (24, '小张3', '女', 20, '计算机'); INSERT INTO "student" VALUES (25, '李四4', '男', 22, '英语'); INSERT INTO "student" VALUES (26, '赵六2', '男', 20, '机械'); INSERT INTO "student" VALUES (27, '小李3', '女', 19, '英语'); INSERT INTO "student" VALUES (28, '王五4', '男', 21, '经管');
创建分页窗口控件
DataGrid.py
from PyQt5.QtWidgets import QWidget class DataGrid(QWidget): def __init__(self): super().__init__() self.setWindowTitle("分页查询例子") self.resize(750, 300) # 查询模型 self.queryModel = None # 数据表 self.tableView = None # 总数页文本 self.totalPageLabel = None # 当前页文本 self.currentPageLabel = None # 转到页输入框 self.switchPageLineEdit = None # 前一页按钮 self.prevButton = None # 后一页按钮 self.nextButton = None # 转到页按钮 self.switchPageButton = None # 当前页 self.currentPage = 0 # 总页数 self.totalPage = 0 # 总记录数 self.totalRecrodCount = 0 # 每页显示记录数 self.PageRecordCount = 5
创建窗口
def createWindow(self): # 操作布局 operatorLayout = QHBoxLayout() self.prevButton = QPushButton("前一页") self.nextButton = QPushButton("后一页") self.switchPageButton = QPushButton("Go") self.switchPageLineEdit = QLineEdit() self.switchPageLineEdit.setFixedWidth(40) switchPage = QLabel("转到第") page = QLabel("页") operatorLayout.addWidget(self.prevButton) operatorLayout.addWidget(self.nextButton) operatorLayout.addWidget(switchPage) operatorLayout.addWidget(self.switchPageLineEdit) operatorLayout.addWidget(page) operatorLayout.addWidget(self.switchPageButton) operatorLayout.addWidget( QSplitter()) # 状态布局 statusLayout = QHBoxLayout() self.totalPageLabel = QLabel() self.totalPageLabel.setFixedWidth(70) self.currentPageLabel = QLabel() self.currentPageLabel.setFixedWidth(70) self.totalRecordLabel = QLabel() self.totalRecordLabel.setFixedWidth(70) statusLayout.addWidget(self.totalPageLabel) statusLayout.addWidget(self.currentPageLabel) statusLayout.addWidget( QSplitter() ) statusLayout.addWidget(self.totalRecordLabel) # 设置表格属性 self.tableView = QTableView() # 表格宽度的自适应调整 self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 创建界面 mainLayout = QVBoxLayout(self); mainLayout.addLayout(operatorLayout); mainLayout.addWidget(self.tableView); mainLayout.addLayout(statusLayout); self.setLayout(mainLayout)
获得表格控件用到的数据
def setTableView(self): print('*** step2 SetTableView' ) self.db = QSqlDatabase.addDatabase('QSQLITE') # 设置数据库名称 self.db.setDatabaseName('/db/database.db') # 打开数据库 self.db.open() # 声明查询模型 self.queryModel = QSqlQueryModel(self) # 设置当前页 self.currentPage = 1; # 得到总记录数 self.totalRecrodCount = self.getTotalRecordCount() # 得到总页数 self.totalPage = self.getPageCount() # 刷新状态 self.updateStatus() # 设置总页数文本 self.setTotalPageLabel() # 设置总记录数 self.setTotalRecordLabel() # 记录查询 self.recordQuery(0) # 设置模型 self.tableView.setModel(self.queryModel) print('totalRecrodCount=' + str(self.totalRecrodCount) ) print('totalPage=' + str(self.totalPage) ) # 设置表格表头 self.queryModel.setHeaderData(0,Qt.Horizontal,"编号") self.queryModel.setHeaderData(1,Qt.Horizontal,"姓名") self.queryModel.setHeaderData(2,Qt.Horizontal,"性别") self.queryModel.setHeaderData(3,Qt.Horizontal,"年龄") self.queryModel.setHeaderData(4,Qt.Horizontal,"院系")
运行测试
完整代码
# -*- coding: utf-8 -*- import sys import re from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QApplication, QPushButton, QLineEdit, QLabel, QSplitter, QTableView, QHeaderView, QMessageBox) from PyQt5.QtCore import Qt from PyQt5.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery def createTableAndInit(): # 添加数据库 db = QSqlDatabase.addDatabase('QSQLITE') # 设置数据库名称 db.setDatabaseName('db/database.db') # 判断是否打开 if not db.open(): return False # 声明数据库查询对象 query = QSqlQuery() # # 创建表 # query.exec("create table student(id int primary key, name vchar, sex vchar, age int, deparment vchar)") # # #添加记录 # query.exec("insert into student values(1,'张三1','男',20,'计算机')") # query.exec("insert into student values(2,'李四1','男',19,'经管')") # query.exec("insert into student values(3,'王五1','男',22,'机械')") # query.exec("insert into student values(4,'赵六1','男',21,'法律')") # query.exec("insert into student values(5,'小明1','男',20,'英语')") # query.exec("insert into student values(6,'小李1','女',19,'计算机')") # query.exec("insert into student values(7,'小张1','男',20,'机械')") # query.exec("insert into student values(8,'小刚1','男',19,'经管')") # query.exec("insert into student values(9,'张三2','男',21,'计算机')") # query.exec("insert into student values(10,'张三3','女',20,'法律')") # query.exec("insert into student values(11,'王五2','男',19,'经管')") # query.exec("insert into student values(12,'张三4','男',20,'计算机')") # query.exec("insert into student values(13,'小李2','男',20,'机械')") # query.exec("insert into student values(14,'李四2','女',19,'经管')") # query.exec("insert into student values(15,'赵六3','男',21,'英语')") # query.exec("insert into student values(16,'李四2','男',19,'法律')") # query.exec("insert into student values(17,'小张2','女',22,'经管')") # query.exec("insert into student values(18,'李四3','男',21,'英语')") # query.exec("insert into student values(19,'小李3','女',19,'法律')") # query.exec("insert into student values(20,'王五3','女',20,'机械')") # query.exec("insert into student values(21,'张三4','男',22,'计算机')") # query.exec("insert into student values(22,'小李2','男',20,'法律')") # query.exec("insert into student values(23,'张三5','男',19,'经管')") # query.exec("insert into student values(24,'小张3','女',20,'计算机')") # query.exec("insert into student values(25,'李四4','男',22,'英语')") # query.exec("insert into student values(26,'赵六2','男',20,'机械')") # query.exec("insert into student values(27,'小李3','女',19,'英语')") # query.exec("insert into student values(28,'王五4','男',21,'经管')") db.close() return True class DataGrid(QWidget): def __init__(self): super().__init__() self.setWindowTitle("分页查询例子") self.resize(750, 300) # 查询模型 self.queryModel = None # 数据表 self.tableView = None # 总数页文本 self.totalPageLabel = None # 当前页文本 self.currentPageLabel = None # 转到页输入框 self.switchPageLineEdit = None # 前一页按钮 self.prevButton = None # 后一页按钮 self.nextButton = None # 转到页按钮 self.switchPageButton = None # 当前页 self.currentPage = 0 # 总页数 self.totalPage = 0 # 总记录数 self.totalRecrodCount = 0 # 每页显示记录数 self.PageRecordCount = 5 self.db = None self.initUI() def initUI(self): # 创建窗口 self.createWindow() # 设置表格 self.setTableView() # 信号槽连接 self.prevButton.clicked.connect(self.onPrevButtonClick) self.nextButton.clicked.connect(self.onNextButtonClick) self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick) def closeEvent(self, event): # 关闭数据库 self.db.close() # 创建窗口 def createWindow(self): # 操作布局 operatorLayout = QHBoxLayout() self.prevButton = QPushButton("前一页") self.nextButton = QPushButton("后一页") self.switchPageButton = QPushButton("Go") self.switchPageLineEdit = QLineEdit() self.switchPageLineEdit.setFixedWidth(40) switchPage = QLabel("转到第") page = QLabel("页") operatorLayout.addWidget(self.prevButton) operatorLayout.addWidget(self.nextButton) operatorLayout.addWidget(switchPage) operatorLayout.addWidget(self.switchPageLineEdit) operatorLayout.addWidget(page) operatorLayout.addWidget(self.switchPageButton) operatorLayout.addWidget(QSplitter()) # 状态布局 statusLayout = QHBoxLayout() self.totalPageLabel = QLabel() self.totalPageLabel.setFixedWidth(70) self.currentPageLabel = QLabel() self.currentPageLabel.setFixedWidth(70) self.totalRecordLabel = QLabel() self.totalRecordLabel.setFixedWidth(70) statusLayout.addWidget(self.totalPageLabel) statusLayout.addWidget(self.currentPageLabel) statusLayout.addWidget(QSplitter()) statusLayout.addWidget(self.totalRecordLabel) # 设置表格属性 self.tableView = QTableView() # 表格宽度的自适应调整 self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 创建界面 mainLayout = QVBoxLayout(self); mainLayout.addLayout(operatorLayout); mainLayout.addWidget(self.tableView); mainLayout.addLayout(statusLayout); self.setLayout(mainLayout) # 设置表格 def setTableView(self): print('*** step2 SetTableView') self.db = QSqlDatabase.addDatabase('QSQLITE') # 设置数据库名称 self.db.setDatabaseName('db/database.db') # 打开数据库 self.db.open() # 声明查询模型 self.queryModel = QSqlQueryModel(self) # 设置当前页 self.currentPage = 1; # 得到总记录数 self.totalRecrodCount = self.getTotalRecordCount() # 得到总页数 self.totalPage = self.getPageCount() # 刷新状态 self.updateStatus() # 设置总页数文本 self.setTotalPageLabel() # 设置总记录数 self.setTotalRecordLabel() # 记录查询 self.recordQuery(0) # 设置模型 self.tableView.setModel(self.queryModel) print('totalRecrodCount=' + str(self.totalRecrodCount)) print('totalPage=' + str(self.totalPage)) # 设置表格表头 self.queryModel.setHeaderData(0, Qt.Horizontal, "编号") self.queryModel.setHeaderData(1, Qt.Horizontal, "姓名") self.queryModel.setHeaderData(2, Qt.Horizontal, "性别") self.queryModel.setHeaderData(3, Qt.Horizontal, "年龄") self.queryModel.setHeaderData(4, Qt.Horizontal, "院系") # 得到记录数 def getTotalRecordCount(self): self.queryModel.setQuery("select * from student") rowCount = self.queryModel.rowCount() print('rowCount=' + str(rowCount)) return rowCount # 得到页数 def getPageCount(self): if self.totalRecrodCount % self.PageRecordCount == 0: return (self.totalRecrodCount / self.PageRecordCount) else: return (self.totalRecrodCount / self.PageRecordCount + 1) # 记录查询 def recordQuery(self, limitIndex): szQuery = ("select * from student limit %d,%d" % (limitIndex, self.PageRecordCount)) print('query sql=' + szQuery) self.queryModel.setQuery(szQuery) # 刷新状态 def updateStatus(self): szCurrentText = ("当前第%d页" % self.currentPage) self.currentPageLabel.setText(szCurrentText) # 设置按钮是否可用 if self.currentPage == 1: self.prevButton.setEnabled(False) self.nextButton.setEnabled(True) elif self.currentPage == self.totalPage: self.prevButton.setEnabled(True) self.nextButton.setEnabled(False) else: self.prevButton.setEnabled(True) self.nextButton.setEnabled(True) # 设置总数页文本 def setTotalPageLabel(self): szPageCountText = ("总共%d页" % self.totalPage) self.totalPageLabel.setText(szPageCountText) # 设置总记录数 def setTotalRecordLabel(self): szTotalRecordText = ("共%d条" % self.totalRecrodCount) print('*** setTotalRecordLabel szTotalRecordText=' + szTotalRecordText) self.totalRecordLabel.setText(szTotalRecordText) # 前一页按钮按下 def onPrevButtonClick(self): print('*** onPrevButtonClick '); limitIndex = (self.currentPage - 2) * self.PageRecordCount self.recordQuery(limitIndex) self.currentPage -= 1 self.updateStatus() # 后一页按钮按下 def onNextButtonClick(self): print('*** onNextButtonClick '); limitIndex = self.currentPage * self.PageRecordCount self.recordQuery(limitIndex) self.currentPage += 1 self.updateStatus() # 转到页按钮按下 def onSwitchPageButtonClick(self): # 得到输入字符串 szText = self.switchPageLineEdit.text() print(szText) # 数字正则表达式 pattern = re.compile(r'^[-+]?[0-9]+\.[0-9]+$') match = pattern.match(szText) # print(match) # # 判断是否为数字 # if not match: # QMessageBox.information(self, "提示", "请输入数字") # return # # # 是否为空 # if szText == '': # QMessageBox.information(self, "提示", "请输入跳转页面") # return # 得到页数 pageIndex = int(szText) # 判断是否有指定页 if pageIndex > self.totalPage or pageIndex < 1: QMessageBox.information(self, "提示", "没有指定的页面,请重新输入") return # 得到查询起始行号 limitIndex = (pageIndex - 1) * self.PageRecordCount # 记录查询 self.recordQuery(limitIndex); # 设置当前页 self.currentPage = pageIndex # 刷新状态 self.updateStatus(); if __name__ == '__main__': from pyqt5_plugins.examples.exampleqmlitem import QtCore QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) app = QApplication(sys.argv) if createTableAndInit(): # 创建窗口 example = DataGrid() # 显示窗口 example.show() sys.exit(app.exec_())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。