【数据库实验】实验四 基于嵌入SQL的综合应用编程

  • 一、实验目的
  • 二、实验要求
  • 三、实验内容、实验结果与主要程序代码
    • 数据准备(建表并插入数据)
    • 前言:黎哥的写法
    • 参考
      • 建表
      • SQL语言插入数据
        • S表
        • SC表
        • C表
      • 嵌入式SQL
        • S表
        • SC表
        • C表
      • 程序按钮组成
      • 备份实现
        • SQLITE的备份保存实现
        • MYSQL数据库备份
      • 主要代码
      • QSqlTableModel和QSqlQueryModel
      • 界面
      • 创建数据库,插入数据表
      • 展示表的全部数据
      • 查找,添加,删除,修改
      • 备份实现(文件函数)
      • 演示GIF
      • 完整代码

一、实验目的

本次实验的主要目的是掌握嵌入SQL及主高级语言,学会使用嵌入SQL对数据库进行增、删、改、备份的方法。

二、实验要求

1.要求学生独立完成实验内容,画出E-R图及程序功能图;
2.按照实验步骤完成实验后,撰写报告内容,并对操作结果进行截图,写出主要关键程序代码。

三、实验内容、实验结果与主要程序代码

基于实验一的三个表采用嵌入式SQL语言及主语言编程实现数据库的录入、修改、删除和备份等管理功能,并能实现基于学号显示学生基本信息、课程名、成绩信息。
(一) 画出E-R图及程序功能分析设计图
(二)功能实现界面图及主要程序代码(要有注释)

数据准备(建表并插入数据)

前言:黎哥的写法

先使用QT写好.ui文件,然后使用pyuic转化为.py文件,在.py文件内,写槽函数,写连接函数写执行函数。使用pymysqlcursor游标,执行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 columnself.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)  # 放置表格位置在0self.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-8import os,sys
from PyQt5 import QtCore, QtWidgets, QtSql
from PyQt5.QtWidgets import QApplication, QMessageBox, QPushButtonclass 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)  # 放置表格位置在0self.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_())

【数据库实验】实验四 基于嵌入SQL的综合应用编程(基于QSqlTableModel实现)相关推荐

  1. mysql安全实验测验答案_实验四∶数据库安全性实验报告.doc

    资源描述 1 / 2实验四:数据库安全性班级:软件工程 0918 姓名:许啸 学号:0911610819[实验目的] :验证数据库安全性[实验要求] :1)新建一个登陆名为 tom,密码为 tom00 ...

  2. SQL server数据库五大实验

    文章目录 前言 实验一 数据库和基本表操作 一.实验目的 二.实验学时 三.实验内容 四.预备知识 实验二 数据操作 一.实验目的 二.实验学时 三.实验内容 四.预备知识 实验三 单表查询 一.实验 ...

  3. oracle数据安全管理实验,第四次Oracle数据库上机实验-bistu

    <第四次Oracle数据库上机实验-bistu>由会员分享,可在线阅读,更多相关<第四次Oracle数据库上机实验-bistu(3页珍藏版)>请在人人文库网上搜索. 1.BIS ...

  4. mysql数据库实验报告四

    实验报告四 实验目的: 实验内容和主要步骤: 实验中遇到的问题和心得体会: 实验目的: 1.熟练掌握SQL的常用数据更新操作. 2.熟练应用INSERT,UPDATE,DELETE语句. 3.掌握更新 ...

  5. 【027】基于Vue+Nodejs+Mysql模仿微博的图片分享系统(管理员、用户两种身份)(含源码、数据库、实验报告、运行教程)

    观前提醒:源码.数据库.实验报告在文末 该Web小型软件系统是基于图片分享的模仿微博社交平台,用户在里面可查看别人分享的内容,同时也可以发布自己的内容.在浏览分享的帖子中,用户可以进行点赞.评论.收藏 ...

  6. 【数据库原理实验(openGauss)】实验报告

    <数据库系统原理实验>报告 文章目录 <数据库系统原理实验>报告 一.实验课程性质和教学目标 二.实验课程教学基本要求 三.实验教学内容 实验一 认识DBMS系统 (一)实验目 ...

  7. 数据库原理实验二 数据库管理 实验报告

    广州大学学生实验报告实验二:数据库管理 此篇分享仅供参考学习,图文禁复制,勿作他用!谢谢配合! 数据库原理实验之实验二:数据库管理 软件:Oracle SQL Developer 今天实验才刚开始,花 ...

  8. 201671010456-张琼 实验十四 团队项目评审课程学习总结

    博文简要信息表 项目 内容 这个作业属于哪个课程 http://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu- ...

  9. 201671030111 李蓉 实验十四 团队项目评审课程学习总结

    项目 内容 这个作业属于哪个课程 软件工程 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程,反思总结课程学习内容. 任务一:结合本学期课程学习 ...

最新文章

  1. 动态生成GridView时,加入DataKeyNames属性,回调时出错解决方法
  2. 一个管理者的反思(太深刻了!)
  3. tf.sparse.SparseTensor
  4. 怎么配置linux中es搜索的主机名,分布式搜索elasticsearch中文分词集成
  5. 矩池云上如何安装nvcc
  6. 一位销售的几年职业总结
  7. NetTraffic网络流量监控工具
  8. 《数据库系统概论》知识整理
  9. TCP: too many of orphaned sockets错误
  10. FBI如何费尽心力破解了苹果,以及,iOS系统究竟有多安全? | 硬创公开课
  11. 自动化办公:1、文件自动化处理邮件批量处理
  12. Scum服务器显示红色,进服务器 提示这个有大神解答一下吗
  13. 人工智能全栈学习路线之人工智能概览(百度云智学院学习笔记)
  14. 东望时代(原中国建筑第一股浙江广厦),将换域名,升级官网为数字化网站
  15. 计算机操作员初级试题及答案,计算机操作员初级考试试题
  16. 【C++探索之旅】开宗明义+第一部分第一课:什么是C++?
  17. SFR 原理分析 代码
  18. 解决Win10家庭版没有‘本地用户和组’问题
  19. python求一元二次方程实根_Python编程实现数学运算求一元二次方程的实根算法示例...
  20. FDTD仿真、解决微环透射率大于1 T大于1的问题

热门文章

  1. Nexus搭建Maven私服并使用私服
  2. python 删除pdf页面_Python脚本使用pyPDF删除空白页面
  3. Ubuntu20.04 conda安出错,成功解决:solving environment:failed with initial frozen solve.Retrying with flexibl
  4. ES6——class类的继承与静态方法
  5. 罗永浩直播卖货,体现了一个年近50岁男人的无奈
  6. Fansblog HDU - 6608
  7. php 涂鸦,微信小程序涂鸦功能的实现
  8. python-字典练习3 -数字重复统计
  9. 蓝桥杯 Python 练习题 数字游戏
  10. Java基础练习--猜数字游戏