【数据库实验】实验四 基于嵌入SQL的综合应用编程
一、实验目的
本次实验的主要目的是掌握嵌入SQL及主高级语言,学会使用嵌入SQL对数据库进行增、删、改、备份的方法。
二、实验要求
1.要求学生独立完成实验内容,画出E-R图及程序功能图;
2.按照实验步骤完成实验后,撰写报告内容,并对操作结果进行截图,写出主要关键程序代码。
三、实验内容、实验结果与主要程序代码
基于实验一的三个表采用嵌入式SQL语言及主语言编程实现数据库的录入、修改、删除和备份等管理功能,并能实现基于学号显示学生基本信息、课程名、成绩信息。
(一) 画出E-R图及程序功能分析设计图
(二)功能实现界面图及主要程序代码(要有注释)
数据准备(建表并插入数据)
前言:黎哥的写法
先使用QT写好.ui
文件,然后使用pyuic
转化为.py
文件,在.py
文件内,写槽函数,写连接函数,写执行函数。使用pymysql
的cursor
游标,执行sql命令。显示数据。
备份的实现,使用了系统命令,具体实现如下所示。
name="root"
key="passwd"
path="D://xxxx/"
os.system("mysql drop -u {1} -p {2} {3} values(%,%,%)".(name,key,path))
参考
PyQt5教程 课时139 使用可视化的方式对SQLite数据库进行增、删、改、查操作
Qt数据库(5)-使用SQLModel类
qtableview add rows from a query and edit them in python
self.model.setTable("produse")
self.produse_view.setModel(self.model)
self.produse_view.hideColumn(0) # hide id column
self.addData(["a", "b", "c", "d", "e", "f"])
def addData(self, data):
rec = self.model.record()
for i in range(6):
rec.setValue(rec.field(i+1).name(), data[i])
self.model.insertRecord(-1, rec)
建表
#建立S学生表
Drop if exists S;
CREATE TABLE S(sclass int,sno int,sname char(20),ssex char(4),sage int,Sdept char(20));
#建立SC选课表
Drop if exists SC;
CREATE TABLE SC(sclass int,sno int,cno int ,grade int);
#建立C课程表
Drop if exists C;
CREATE TABLE C(cno int,cname char(20),cpno int,ccredit int);
SQL语言插入数据
S表
INSERT INTO S VALUES(1,1,'李勇','男',20,'IS');
INSERT INTO S VALUES(1,2,'刘晨','女',19,'IS');
INSERT INTO S VALUES(1,3,'刘朋','男',20,'IS');
INSERT INTO S VALUES(2,1,'王敏','女',18,'MA');
INSERT INTO S VALUES(2,2,'张锋','男',19,'MA');
INSERT INTO S VALUES(2,3,'李敏','男',20,'MA');
SC表
INSERT INTO SC VALUES(1,1,1,92);
INSERT INTO SC VALUES(1,1,2,85);
INSERT INTO SC VALUES(1,1,3,88);
INSERT INTO SC VALUES(1,2,2,90);
INSERT INTO SC VALUES(1,2,3,80);
INSERT INTO SC VALUES(2,1,1,75);
INSERT INTO SC VALUES(2,1,2,92);
INSERT INTO SC VALUES(2,2,2,87);
INSERT INTO SC VALUES(2,2,3,89);
INSERT INTO SC VALUES(2,3,1,90);
C表
INSERT INTO C VALUES(1,'数据库',5,4);
INSERT INTO C VALUES(2,'数学',NULL,2);
INSERT INTO C VALUES(3,'信息系统',1,4);
INSERT INTO C VALUES(4,'操作系统',6,3);
INSERT INTO C VALUES(5,'数据结构',7,4);
INSERT INTO C VALUES(6,'数据处理',NULL,2);
INSERT INTO C VALUES(7,'PASCAL语言',6,4);
嵌入式SQL
S表
query.exec_ ("INSERT INTO S VALUES(1,1,'李勇','男',20,'IS')")
query.exec_ ("INSERT INTO S VALUES(1,2,'刘晨','女',19,'IS')")
query.exec_ ("INSERT INTO S VALUES(1,3,'刘朋','男',20,'IS')")
query.exec_ ("INSERT INTO S VALUES(2,1,'王敏','女',18,'MA')")
query.exec_ ("INSERT INTO S VALUES(2,2,'张锋','男',19,'MA')")
query.exec_ ("INSERT INTO S VALUES(2,3,'李敏','男',20,'MA')")
SC表
query.exec_("INSERT INTO SC VALUES(1,1,1,92)")
query.exec_("INSERT INTO SC VALUES(1,1,2,85)")
query.exec_("INSERT INTO SC VALUES(1,1,3,88)")
query.exec_("INSERT INTO SC VALUES(1,2,2,90)")
query.exec_("INSERT INTO SC VALUES(1,2,3,80)")
query.exec_("INSERT INTO SC VALUES(2,1,1,75)")
query.exec_("INSERT INTO SC VALUES(2,1,2,92)")
query.exec_("INSERT INTO SC VALUES(2,2,2,87)")
query.exec_("INSERT INTO SC VALUES(2,2,3,89)")
query.exec_("INSERT INTO SC VALUES(2,3,1,90)")
C表
query.exec_("INSERT INTO C VALUES(1,'数据库',5,4)")
query.exec_("INSERT INTO C VALUES(2,'数学',NULL,2)")
query.exec_("INSERT INTO C VALUES(3,'信息系统',1,4)")
query.exec_("INSERT INTO C VALUES(4,'操作系统',6,3)")
query.exec_("INSERT INTO C VALUES(5,'数据结构',7,4)")
query.exec_("INSERT INTO C VALUES(6,'数据处理',NULL,2)")
query.exec_("INSERT INTO C VALUES(7,'PASCAL语言',6,4)")
程序按钮组成
按实验要求,需要有基于学号的检索数据功能,插入数据功能,删除数据功能,以及备份数据库功能。
首先建立数据库一个按钮,
然后显示一个按钮,
然后查询一个按钮,
然后删除一个按钮,
然后修改一个按钮,
然后备份一个按钮,
最后退出一个按钮。
共计7个按钮。
在这里插入代码片
备份实现
SQLITE的备份保存实现
保存的本质是把当前sqlite文件进行另存为保存。
保存图片
from tkinter import *
fname = tkinter.filedialog.asksaveasfilename(title=u'保存文件', filetypes=[("PNG", ".png")])
picture.save(str(fname) + '.png', 'PNG')
只需要在弹出对话框后选择保存位置,输入图片名字即可。
【注】如果不加以下两行代码:
root = tkinter.Tk() # 创建一个Tkinter.Tk()实例
root.withdraw() # 将Tkinter.Tk()实例隐藏
程序运行后将会出现一个小框。
MYSQL数据库备份
对于其他数据库,比如MYSQL数据库来说:
使用Python3编写脚本一键备份MySQL数据库
使用的是subprocess
import logging
import os
import subprocess
import pymysql
- 备份
logging.info('开始备份数据库 {}...'.format(database))
# 通过调用mysqldump完成指定数据库的备份
command = 'mysqldump -h192.168.1.4 -uroot -p666 --add-drop-database --databases {database} > {backup_path}/{database}.sql'.format(
database=database,
backup_path=BACKUP_PATH)
exit_code = subprocess.call(command, shell=True)
# 判断命令是否正常执行,异常则直接抛出
if exit_code != 0:
raise Exception('在备份数据库的过程中出错,请检查!')
logging.info('数据库 {} 备份完毕!'.format(database))
- 恢复
import logging
import os
import subprocess
import pymysql
# 设置日志输出格式
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',level=logging.INFO)
# MySQL数据库用户名
MYSQL_USERNAME = 'root'
# 数据库密码
MYSQL_PASSWORD = 'mypassword'
# 数据库主机地址
MYSQL_HOST = '192.168.1.4'
# 数据库端口
MYSQL_PORT = 3306
# 备份文件存放路径
BACKUP_PATH = 'backup'
logging.info('开始获取需要恢复的数据库文件...')
files = list(os.listdir(BACKUP_PATH))
logging.info('文件列表:{}'.format(files))
# 开始逐个恢复数据库
for file in files:
logging.info('开始恢复数据库 {}...'.format(file.split('.')[0]))
command = 'mysql -h{host} -f -u{user} -p{password} -P{port} < {path}/{file}'.format(host=MYSQL_HOST, user=MYSQL_USERNAME, password=MYSQL_PASSWORD, port=MYSQL_PORT, file=file, path=BACKUP_PATH)
subprocess.call(command, shell=True)
logging.info('完毕!')
主要代码
最简单的库引用的写法:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtSql import *
QSqlTableModel和QSqlQueryModel
QSqlQuery
可以用来执行SQL语句和获得执行结果的。
QSqlQueryModel
提供了一个sql查询结果的只读数据模型。它从查询QSqlQueryModel获取数据。
可以方便的用于在QListView, QTableView, QTreeView等各种view上展示数据。
但它是只读的,不能编辑。
QSqlTableMode
继承于QSqlQueryModel,与QSqlQueryModel功能相似。
比QSqlQueryModel的限制在于不能是任意sql语句,只是对单个数据表操作。
拓展在于在各种view上展示表格数据的同时,还允许用户进行编辑操作。
bool QSqlTableModel:: select ()
使用通过setTable ()
设置的表中的数据填充模型,使用指定的过滤器(setFilter()
)和排序条件,true如果成功则返回;否则返回false。
注意:调用 select()
将恢复任何未提交的更改并删除任何插入的列。
另请参见setTable ()
、setFilter ()
和selectStatement ()
。
界面
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
# 设置窗口标题
self.setWindowTitle("刘看日的数据库实验四")
# 设置窗口大小
self.resize(600, 400)
# 创建一个窗口部件
self.widget = QtWidgets.QWidget()
# 创建一个网格布局
self.grid_layout = QtWidgets.QGridLayout()
# 设置窗口部件的布局为网格布局
self.widget.setLayout(self.grid_layout)
# 创建一个工具组
self.group_box = QtWidgets.QGroupBox('功能按钮')
self.group_box_layout = QtWidgets.QVBoxLayout()
self.group_box.setLayout(self.group_box_layout)
#设置一个LineEdit窗口
self.text=QtWidgets.QLineEdit()
# 设置文本框的默认浮现文本
self.text.setPlaceholderText("输入学号/课程号")
self.table_view = QtWidgets.QTableView()
# 按钮控件设置
self.btn_create=QPushButton("连接表")
self.btn_showall=QPushButton("展示全部数据")
self.btn_search = QPushButton("基于学号/课程号查询")
self.btn_close = QPushButton("退出")
self.btn_delete=QPushButton("删除")
self.btn_edit=QPushButton("修改")
self.btn_add=QPushButton("添加")
self.btn_backup = QPushButton("备份")
# 添加按钮到group_box大组件中
self.group_box_layout.addWidget(self.text)
self.group_box_layout.addWidget(self.btn_create)
self.group_box_layout.addWidget(self.btn_showall)
self.group_box_layout.addWidget(self.btn_search)
self.group_box_layout.addWidget(self.btn_add)
self.group_box_layout.addWidget(self.btn_delete)
self.group_box_layout.addWidget(self.btn_edit)
self.group_box_layout.addWidget(self.btn_backup)
self.group_box_layout.addWidget(self.btn_close)
# 将上述两个部件添加到网格布局中
self.grid_layout.addWidget(self.table_view, 0, 0) # 放置表格位置在0
self.grid_layout.addWidget(self.group_box, 0, 1) # 放置
# 创建按钮功能按钮
self.btn_create.clicked.connect(self.create_db)
self.btn_showall.clicked.connect(self.showall_tab)
self.btn_search.clicked.connect(self.search_data)
self.btn_close.clicked.connect(self.close)
self.btn_add.clicked.connect(self.add_row_data)
self.btn_delete.clicked.connect(self.del_row_data)
self.btn_edit.clicked.connect(self.edit_row_data)
self.btn_backup.clicked.connect(self.backup_data)
# 设置UI界面的核心部件
self.setCentralWidget(self.widget)
创建数据库,插入数据表
def create_db(self):
# 添加一个mysql数据库连接并打开
db = QtSql.QSqlDatabase.addDatabase('QSQLITE') # 创建Mysql数据库,可自定义
if db.setDatabaseName('student.sqlite'): # 设置数据库名称
print("创建'student.sqlite'数据库文件成功")
msgBox1 = QMessageBox()
msgBox1.setText("创建'student.sqlite'数据库文件成功")
msgBox1.exec()
else:
print("'student.sqlite'数据文件已经存在")
msgBox2 = QMessageBox()
msgBox2.setText("'student.sqlite'数据文件已经存在")
msgBox2.exec()
db.setHostName("127.0.0.1")#可以有多个连接到同一个数据库,也就是说连接名不唯一
db.setUserName('tom')#定义用户名
db.setPassword('tom@123')#定义密码
# success!
db.open()
table_text, table_action = QtWidgets.QInputDialog.getText(self, '表名称', '请输入表名称', QtWidgets.QLineEdit.Normal)
if (table_text.replace(' ', '') != '') and (table_action is True):
print(table_text)
#实例化一个查询对象
self.tablename=table_text
#先进行插入数据
query = QtSql.QSqlQuery()
if query.exec_("Drop table if exists s"):
print("drop table s ok!")
if query.exec_("CREATE TABLE S(sclass int,sno int,sname char(20),ssex char(4),sage int,Sdept char(20))"):
print("create table s ok!")
if query.exec_("Drop table if exists sc"):
print("drop table sc ok!")
if query.exec_("CREATE TABLE SC(sclass int,sno int,cno int ,grade int)"):
print("create table sc ok!")
if query.exec_("Drop table if exists c"):
print("drop table c ok!")
else:
print("error:drop table c")
if query.exec_("CREATE TABLE C(cno int,cname char(20),cpno int,ccredit int)"):
print("create table c ok!")
else:
print("error:create table c")
query.exec_("INSERT INTO S VALUES(1,1,'李勇','男',20,'IS')")
query.exec_("INSERT INTO S VALUES(1,2,'刘晨','女',19,'IS')")
query.exec_("INSERT INTO S VALUES(1,3,'刘朋','男',20,'IS')")
query.exec_("INSERT INTO S VALUES(2,1,'王敏','女',18,'MA')")
query.exec_("INSERT INTO S VALUES(2,2,'张锋','男',19,'MA')")
query.exec_("INSERT INTO S VALUES(2,3,'李敏','男',20,'MA')")
query.exec_("INSERT INTO SC VALUES(1,1,1,92)")
query.exec_("INSERT INTO SC VALUES(1,1,2,85)")
query.exec_("INSERT INTO SC VALUES(1,1,3,88)")
query.exec_("INSERT INTO SC VALUES(1,2,2,90)")
query.exec_("INSERT INTO SC VALUES(1,2,3,80)")
query.exec_("INSERT INTO SC VALUES(2,1,1,75)")
query.exec_("INSERT INTO SC VALUES(2,1,2,92)")
query.exec_("INSERT INTO SC VALUES(2,2,2,87)")
query.exec_("INSERT INTO SC VALUES(2,2,3,89)")
query.exec_("INSERT INTO SC VALUES(2,3,1,90)")
query.exec_("INSERT INTO SC VALUES(1,1,1,92)")
query.exec_("INSERT INTO SC VALUES(1,1,2,85)")
query.exec_("INSERT INTO SC VALUES(1,1,3,88)")
query.exec_("INSERT INTO SC VALUES(1,2,2,90)")
query.exec_("INSERT INTO SC VALUES(1,2,3,80)")
query.exec_("INSERT INTO SC VALUES(2,1,1,75)")
query.exec_("INSERT INTO SC VALUES(2,1,2,92)")
query.exec_("INSERT INTO SC VALUES(2,2,2,87)")
query.exec_("INSERT INTO SC VALUES(2,2,3,89)")
query.exec_("INSERT INTO SC VALUES(2,3,1,90)")
db.close()
展示表的全部数据
def showall_tab(self):
query = QtSql.QSqlQuery()
if (self.tablename == "s"):
msgBox3 = QMessageBox()
msgBox3.setText("展示表s")
msgBox3.exec()
self.model = QtSql.QSqlTableModel(
self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
# model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '姓名')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '性别')
self.model.setHeaderData(4, QtCore.Qt.Horizontal, '年龄')
self.model.setHeaderData(5, QtCore.Qt.Horizontal, '院系')
self.model.setTable("s")
self.model.select()
self.table_view.setModel(self.model) # 一定要写在所有设置完之后,装载数据
elif (self.tablename == "sc"):
msgBox4 = QMessageBox()
msgBox4.setText("展示表sc")
msgBox4.exec()
self.model = QtSql.QSqlTableModel(
self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
# model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '成绩')
self.model.setTable("sc")
self.model.select()
self.table_view.setModel(self.model) # 一定要写在所有设置完之后,装载数据
elif (self.tablename == "c"):
msgBox5 = QMessageBox()
msgBox5.setText("展示表c")
msgBox5.exec()
self.model = QtSql.QSqlTableModel(self.table_view)
# onfieldchange模型的任何更改都会返回到数据库
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '课程名')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '先修课')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '学分')
self.model.setTable("c")
self.model.select()
self.table_view.setModel(self.model)
else:
msgBox6 = QMessageBox()
msgBox6.setText("表暂且不属于实验范围,请更换!")
msgBox6.exec_()
查找,添加,删除,修改
def search_data(self):
query = QtSql.QSqlQuery()
# 创建一个数据库表
if(self.tablename=="s"):
msgBox3 = QMessageBox()
msgBox3.setText("查询表s")
msgBox3.exec()
self.model = QtSql.QSqlTableModel(self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
#model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '姓名')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '性别')
self.model.setHeaderData(4, QtCore.Qt.Horizontal, '年龄')
self.model.setHeaderData(5, QtCore.Qt.Horizontal, '院系')
search = self.text.text()
self.model.setTable("s")
self.model.setFilter("sno={}".format(search))
self.model.select()
self.table_view.setModel(self.model)#一定要写在所有设置完之后,装载数据
elif(self.tablename=="sc"):
msgBox4 = QMessageBox()
msgBox4.setText("查询表sc")
msgBox4.exec()
self.model = QtSql.QSqlTableModel(self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
#model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '成绩')
search = self.text.text()
self.model.setTable("sc")
self.model.setFilter("sno = {}".format(search))
self.model.select()
self.table_view.setModel(self.model)#一定要写在所有设置完之后,装载数据
elif(self.tablename=="c"):
msgBox5 = QMessageBox()
msgBox5.setText("查询表c")
msgBox5.exec()
self.model=QtSql.QSqlTableModel(self.table_view)
#onfieldchange模型的任何更改都会返回到数据库
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.model.setHeaderData(0,QtCore.Qt.Horizontal,'课程号')
self.model.setHeaderData(1,QtCore.Qt.Horizontal,'课程名')
self.model.setHeaderData(2,QtCore.Qt.Horizontal,'先修课')
self.model.setHeaderData(3,QtCore.Qt.Horizontal,'学分')
search=self.text.text()
self.model.setTable("c")
self.model.setFilter("cno = {}".format(search))
self.model.select()
self.table_view.setModel(self.model)
else:
msgBox6=QMessageBox()
msgBox6.setText("表暂且不属于实验范围,请更换!")
msgBox6.exec_()
def add_row_data(self):
#不是直接操作QTableView,而是对model模型进行添加
# 如果存在实例化的数据模型对象
# self.model.insertRow(self.model.rowCount(),1)
if self.model:
#rowCount()得到行数,然后添加一行
self.model.insertRows(self.model.rowCount(), 1)
self.model.submitAll()#提交修改
else:
self.create_db()
def del_row_data(self):
if self.model:
self.model.removeRow(self.table_view.currentIndex().row())
self.model.submitAll()#提交修改
else:
self.create_db()
def edit_row_data(self):
if self.model:
self.model.submitAll()#提交更改
else:
self.create_db()
备份实现(文件函数)
def backup_data(self):
ori_file_name = r'D:\coding_programs\PythonPrograms\database_exp4\student.sqlite' # 输入文件路径
if os.path.isfile(ori_file_name): # 判断该路径的是否是文件
# 截取文件名,重组文件名
seek_num = ori_file_name.rfind('.')
new_file_name = ori_file_name[:seek_num] + '.bak'
# 打开源文件
old_file = open(ori_file_name, 'rb')
# 读取文件信息
old_file_content = old_file.read()
# 创建新文件
new_file = open(new_file_name, 'wb')
# 将原始文件信息写入
new_file.write(old_file_content)
# 关闭文件
old_file.close()
new_file.close()
print("backup success!")
msgBox7 = QMessageBox()
msgBox7.setText("student.bak数据文件已经备份")
msgBox7.exec()
else:
print('没有该文件')
演示GIF
完整代码
# coding:utf-8
import os,sys
from PyQt5 import QtCore, QtWidgets, QtSql
from PyQt5.QtWidgets import QApplication, QMessageBox, QPushButton
class MainUi(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUi()
def create_db(self):
# 添加一个mysql数据库连接并打开
db = QtSql.QSqlDatabase.addDatabase('QSQLITE') # 创建Mysql数据库,可自定义
if db.setDatabaseName('student.sqlite'): # 设置数据库名称
print("创建'student.sqlite'数据库文件成功")
msgBox1 = QMessageBox()
msgBox1.setText("创建'student.sqlite'数据库文件成功")
msgBox1.exec()
else:
print("'student.sqlite'数据文件已经存在")
msgBox2 = QMessageBox()
msgBox2.setText("'student.sqlite'数据文件已经存在")
msgBox2.exec()
db.setHostName("127.0.0.1")#可以有多个连接到同一个数据库,也就是说连接名不唯一
db.setUserName('tom')#定义用户名
db.setPassword('tom@123')
# success!
db.open()
table_text, table_action = QtWidgets.QInputDialog.getText(self, '表名称', '请输入表名称', QtWidgets.QLineEdit.Normal)
if (table_text.replace(' ', '') != '') and (table_action is True):
print(table_text)
#实例化一个查询对象
self.tablename=table_text
#先进行插入数据
query = QtSql.QSqlQuery()
if query.exec_("Drop table if exists s"):
print("drop table s ok!")
if query.exec_("CREATE TABLE S(sclass int,sno int,sname char(20),ssex char(4),sage int,Sdept char(20))"):
print("create table s ok!")
if query.exec_("Drop table if exists sc"):
print("drop table sc ok!")
if query.exec_("CREATE TABLE SC(sclass int,sno int,cno int ,grade int)"):
print("create table sc ok!")
if query.exec_("Drop table if exists c"):
print("drop table c ok!")
else:
print("error:drop table c")
if query.exec_("CREATE TABLE C(cno int,cname char(20),cpno int,ccredit int)"):
print("create table c ok!")
else:
print("error:create table c")
query.exec_("INSERT INTO S VALUES(1,1,'李勇','男',20,'IS')")
query.exec_("INSERT INTO S VALUES(1,2,'刘晨','女',19,'IS')")
query.exec_("INSERT INTO S VALUES(1,3,'刘朋','男',20,'IS')")
query.exec_("INSERT INTO S VALUES(2,1,'王敏','女',18,'MA')")
query.exec_("INSERT INTO S VALUES(2,2,'张锋','男',19,'MA')")
query.exec_("INSERT INTO S VALUES(2,3,'李敏','男',20,'MA')")
query.exec_("INSERT INTO SC VALUES(1,1,1,92)")
query.exec_("INSERT INTO SC VALUES(1,1,2,85)")
query.exec_("INSERT INTO SC VALUES(1,1,3,88)")
query.exec_("INSERT INTO SC VALUES(1,2,2,90)")
query.exec_("INSERT INTO SC VALUES(1,2,3,80)")
query.exec_("INSERT INTO SC VALUES(2,1,1,75)")
query.exec_("INSERT INTO SC VALUES(2,1,2,92)")
query.exec_("INSERT INTO SC VALUES(2,2,2,87)")
query.exec_("INSERT INTO SC VALUES(2,2,3,89)")
query.exec_("INSERT INTO SC VALUES(2,3,1,90)")
query.exec_("INSERT INTO SC VALUES(1,1,1,92)")
query.exec_("INSERT INTO SC VALUES(1,1,2,85)")
query.exec_("INSERT INTO SC VALUES(1,1,3,88)")
query.exec_("INSERT INTO SC VALUES(1,2,2,90)")
query.exec_("INSERT INTO SC VALUES(1,2,3,80)")
query.exec_("INSERT INTO SC VALUES(2,1,1,75)")
query.exec_("INSERT INTO SC VALUES(2,1,2,92)")
query.exec_("INSERT INTO SC VALUES(2,2,2,87)")
query.exec_("INSERT INTO SC VALUES(2,2,3,89)")
query.exec_("INSERT INTO SC VALUES(2,3,1,90)")
db.close()
def showall_tab(self):
query = QtSql.QSqlQuery()
if (self.tablename == "s"):
msgBox3 = QMessageBox()
msgBox3.setText("展示表s")
msgBox3.exec()
self.model = QtSql.QSqlTableModel(
self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
# model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '姓名')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '性别')
self.model.setHeaderData(4, QtCore.Qt.Horizontal, '年龄')
self.model.setHeaderData(5, QtCore.Qt.Horizontal, '院系')
self.model.setTable("s")
self.model.select()
self.table_view.setModel(self.model) # 一定要写在所有设置完之后,装载数据
elif (self.tablename == "sc"):
msgBox4 = QMessageBox()
msgBox4.setText("展示表sc")
msgBox4.exec()
self.model = QtSql.QSqlTableModel(
self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
# model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '成绩')
self.model.setTable("sc")
self.model.select()
self.table_view.setModel(self.model) # 一定要写在所有设置完之后,装载数据
elif (self.tablename == "c"):
msgBox5 = QMessageBox()
msgBox5.setText("展示表c")
msgBox5.exec()
self.model = QtSql.QSqlTableModel(self.table_view)
# onfieldchange模型的任何更改都会返回到数据库
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '课程名')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '先修课')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '学分')
self.model.setTable("c")
self.model.select()
self.table_view.setModel(self.model)
else:
msgBox6 = QMessageBox()
msgBox6.setText("表暂且不属于实验范围,请更换!")
msgBox6.exec_()
def search_data(self):
query = QtSql.QSqlQuery()
# 创建一个数据库表
if(self.tablename=="s"):
msgBox3 = QMessageBox()
msgBox3.setText("查询表s")
msgBox3.exec()
self.model = QtSql.QSqlTableModel(self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
#model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '姓名')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '性别')
self.model.setHeaderData(4, QtCore.Qt.Horizontal, '年龄')
self.model.setHeaderData(5, QtCore.Qt.Horizontal, '院系')
search = self.text.text()
self.model.setTable("s")
self.model.setFilter("sno={}".format(search))
self.model.select()
self.table_view.setModel(self.model)#一定要写在所有设置完之后,装载数据
elif(self.tablename=="sc"):
msgBox4 = QMessageBox()
msgBox4.setText("查询表sc")
msgBox4.exec()
self.model = QtSql.QSqlTableModel(self.table_view) # 创建一个空的 QSqlTableModel 并将父级设置为父级,将数据库连接设置为 db。如果 db 无效,则将使用默认数据库连接。
#model 用于装载变量
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '班号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '学号')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '课程号')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '成绩')
search = self.text.text()
self.model.setTable("sc")
self.model.setFilter("sno = {}".format(search))
self.model.select()
self.table_view.setModel(self.model)#一定要写在所有设置完之后,装载数据
elif(self.tablename=="c"):
msgBox5 = QMessageBox()
msgBox5.setText("查询表c")
msgBox5.exec()
self.model=QtSql.QSqlTableModel(self.table_view)
#onfieldchange模型的任何更改都会返回到数据库
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.model.setHeaderData(0,QtCore.Qt.Horizontal,'课程号')
self.model.setHeaderData(1,QtCore.Qt.Horizontal,'课程名')
self.model.setHeaderData(2,QtCore.Qt.Horizontal,'先修课')
self.model.setHeaderData(3,QtCore.Qt.Horizontal,'学分')
search=self.text.text()
self.model.setTable("c")
self.model.setFilter("cno = {}".format(search))
self.model.select()
self.table_view.setModel(self.model)
else:
msgBox6=QMessageBox()
msgBox6.setText("表暂且不属于实验范围,请更换!")
msgBox6.exec_()
def add_row_data(self):
#不是直接操作QTableView,而是对model模型进行添加
# 如果存在实例化的数据模型对象
# self.model.insertRow(self.model.rowCount(),1)
if self.model:
#rowCount()得到行数,然后添加一行
self.model.insertRows(self.model.rowCount(), 1)
self.model.submitAll()#提交修改
else:
self.create_db()
def del_row_data(self):
if self.model:
self.model.removeRow(self.table_view.currentIndex().row())
self.model.submitAll()#提交修改
else:
self.create_db()
def edit_row_data(self):
if self.model:
self.model.submitAll()#提交更改
else:
self.create_db()
def backup_data(self):
ori_file_name = r'D:\coding_programs\PythonPrograms\database_exp4\student.sqlite' # 输入文件路径
if os.path.isfile(ori_file_name): # 判断该路径的是否是文件
# 截取文件名,重组文件名
seek_num = ori_file_name.rfind('.')
new_file_name = ori_file_name[:seek_num] + '.bak'
# 打开源文件
old_file = open(ori_file_name, 'rb')
# 读取文件信息
old_file_content = old_file.read()
# 创建新文件
new_file = open(new_file_name, 'wb')
# 将原始文件信息写入
new_file.write(old_file_content)
# 关闭文件
old_file.close()
new_file.close()
print("backup success!")
msgBox7 = QMessageBox()
msgBox7.setText("student.bak数据文件已经备份")
msgBox7.exec()
else:
print('没有该文件')
def initUi(self):
# 设置窗口标题
self.setWindowTitle("刘看日的数据库实验四")
# 设置窗口大小
self.resize(600, 400)
# 创建一个窗口部件
self.widget = QtWidgets.QWidget()
# 创建一个网格布局
self.grid_layout = QtWidgets.QGridLayout()
# 设置窗口部件的布局为网格布局
self.widget.setLayout(self.grid_layout)
# 创建一个工具组
self.group_box = QtWidgets.QGroupBox('功能按钮')
self.group_box_layout = QtWidgets.QVBoxLayout()
self.group_box.setLayout(self.group_box_layout)
#设置一个LineEdit窗口
self.text=QtWidgets.QLineEdit()
# 设置文本框的默认浮现文本
self.text.setPlaceholderText("输入学号/课程号")
self.table_view = QtWidgets.QTableView()
# 按钮控件设置
self.btn_create=QPushButton("连接表")
self.btn_showall=QPushButton("展示全部数据")
self.btn_search = QPushButton("基于学号/课程号查询")
self.btn_close = QPushButton("退出")
self.btn_delete=QPushButton("删除")
self.btn_edit=QPushButton("修改")
self.btn_add=QPushButton("添加")
self.btn_backup = QPushButton("备份")
# 添加按钮到group_box大组件中
self.group_box_layout.addWidget(self.text)
self.group_box_layout.addWidget(self.btn_create)
self.group_box_layout.addWidget(self.btn_showall)
self.group_box_layout.addWidget(self.btn_search)
self.group_box_layout.addWidget(self.btn_add)
self.group_box_layout.addWidget(self.btn_delete)
self.group_box_layout.addWidget(self.btn_edit)
self.group_box_layout.addWidget(self.btn_backup)
self.group_box_layout.addWidget(self.btn_close)
# 将上述两个部件添加到网格布局中
self.grid_layout.addWidget(self.table_view, 0, 0) # 放置表格位置在0
self.grid_layout.addWidget(self.group_box, 0, 1) # 放置
# 创建按钮功能按钮
self.btn_create.clicked.connect(self.create_db)
self.btn_showall.clicked.connect(self.showall_tab)
self.btn_search.clicked.connect(self.search_data)
self.btn_close.clicked.connect(self.close)
self.btn_add.clicked.connect(self.add_row_data)
self.btn_delete.clicked.connect(self.del_row_data)
self.btn_edit.clicked.connect(self.edit_row_data)
self.btn_backup.clicked.connect(self.backup_data)
# 设置UI界面的核心部件
self.setCentralWidget(self.widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = MainUi()
gui.show()
sys.exit(app.exec_())