溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行PyQt5數(shù)據(jù)庫(kù)操作

發(fā)布時(shí)間:2021-11-11 09:20:45 來(lái)源:億速云 閱讀:197 作者:柒染 欄目:編程語(yǔ)言

如何進(jìn)行PyQt5數(shù)據(jù)庫(kù)操作,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

PyQt5數(shù)據(jù)庫(kù)操作

一、SQLite數(shù)據(jù)庫(kù)

1、SQLite簡(jiǎn)介

SQLite是一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù),實(shí)現(xiàn)了自給自足、無(wú)服務(wù)器、零配置、事務(wù)性的SQL數(shù)據(jù)庫(kù)引擎,主要作為手機(jī)應(yīng)用的數(shù)據(jù)庫(kù)以及小型桌面應(yīng)用的數(shù)據(jù)庫(kù)。
官方網(wǎng)站:
https://www.sqlite.org

2、SQLite常用操作

創(chuàng)建數(shù)據(jù)庫(kù)文件,創(chuàng)建后進(jìn)行入SQLite命令行模式。
sqlite3 DatabaseName.db
查看已經(jīng)存在的數(shù)據(jù)庫(kù)文件,在SQLite命令行模式執(zhí)行:
.databases
打開(kāi)已經(jīng)存在的數(shù)據(jù)庫(kù)文件,如果數(shù)據(jù)庫(kù)文件不存在,則創(chuàng)建。
sqlite3 DatabaseName.db
查看幫助信息,在SQLite命令行模式執(zhí)行:
.help
創(chuàng)建表,在SQLite命令行模式執(zhí)行:
create table person(id integer primary key, name text);
插入數(shù)據(jù)到表:
insert into person(id, name) values(1, "zhangsan");
查詢操作:
select * from person;
查詢表的結(jié)構(gòu):
.schema person

3、SQLite管理工具

SQLite有多個(gè)開(kāi)源且優(yōu)秀的DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng)),提供了界面操作SQLite數(shù)據(jù)庫(kù)。
SQLiteStudio是一款非常專業(yè)的SQLite數(shù)據(jù)庫(kù)管理軟件,體積小巧,功能強(qiáng)大,支持中文,免安裝。
SQLiteStudio下載:
https://sqlitestudio.pl/index.rvt?act=download

二、連接數(shù)據(jù)庫(kù)

1、數(shù)據(jù)庫(kù)驅(qū)動(dòng)類型

PyQt中,QSqlDatabase類用于連接數(shù)據(jù)庫(kù),可以使用數(shù)據(jù)庫(kù)驅(qū)動(dòng)與不同的數(shù)據(jù)庫(kù)進(jìn)行交互,一個(gè)QSqlDatabase實(shí)例代表一次數(shù)據(jù)庫(kù)連接??捎脭?shù)據(jù)庫(kù)驅(qū)動(dòng)類型如下:
QDB2            IBM DB2驅(qū)動(dòng)程序
QMYSQL      MySQL驅(qū)動(dòng)程序
QOCI            Oracle調(diào)用接口驅(qū)動(dòng)程序
QODBC       ODBC驅(qū)動(dòng)程序(包括MS SQL Server)
QPSQL       PostgreSQL驅(qū)動(dòng)程序
QSQLITE     SQLite3驅(qū)動(dòng)程序
QSQLITE2    SQLite2驅(qū)動(dòng)程序

2、QSqlDatabase常用方法

QSqlDatabase常用方法如下:
addDataBase:設(shè)置連接數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)驅(qū)動(dòng)類型
setDatabaseName:設(shè)置所連接的數(shù)據(jù)庫(kù)名稱
setHostName:設(shè)置數(shù)據(jù)庫(kù)所在的主機(jī)名稱
setUserName:指定連接的用戶名
setPassword:設(shè)置連接對(duì)象的密碼
commit:提交事務(wù),如果執(zhí)行成功返回True。
rollback:回滾數(shù)據(jù)庫(kù)事務(wù)
close:關(guān)閉數(shù)據(jù)庫(kù)連接

3、數(shù)據(jù)庫(kù)連接實(shí)例

import sys
from PyQt5.QtSql import QSqlDatabase
from PyQt5.QtCore import *

if __name__ == "__main__":
    app = QCoreApplication(sys.argv)
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("/home/user/test.db")
    if db.open():
        print("open DB success.")
    sys.exit(app.exec_())

三、執(zhí)行SQL語(yǔ)句

QSqlQuery具有執(zhí)行和操作SQL語(yǔ)句的功能,可以執(zhí)行DDL和DML類型的SQL查詢,QSqlQuery.exec_()用于執(zhí)行SQL操作。

import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtCore import *

def createDB():
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("/home/user/test.db")
    if db.open():
        query = QSqlQuery()
        query.exec_("create table person(id int primary key, name varchar(20), address varchar(30))")
        query.exec_("insert into person values(1, 'Bauer', 'beijing')")
        query.exec_("insert into person values(2, 'Jack', 'shanghai')")
        query.exec_("insert into person values(3, 'Alex', 'chengdu')")

        db.close()

if __name__ == "__main__":
    app = QCoreApplication(sys.argv)
    createDB()
    sys.exit(app.exec_())

執(zhí)行完SQL語(yǔ)句后,如果沒(méi)有其它數(shù)據(jù)庫(kù)操作,需要使用db.close關(guān)閉數(shù)據(jù)庫(kù)連接,因?yàn)閿?shù)據(jù)庫(kù)連接資源是有限的,不再使用的數(shù)據(jù)庫(kù)連接必須關(guān)閉,否則數(shù)據(jù)庫(kù)連接資源最終會(huì)被耗盡,導(dǎo)致程序無(wú)法正常連接數(shù)據(jù)庫(kù)。
如果在PyQt的窗口中需要讀取數(shù)據(jù)庫(kù)的數(shù)據(jù)并進(jìn)行顯示,則需要在窗口初始化時(shí)打開(kāi)數(shù)據(jù)庫(kù),在窗口關(guān)閉時(shí)關(guān)閉數(shù)據(jù)庫(kù)連接。

import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("/home/user/test.db")
        self.db.open()

    def closeEvent(self, event):
        self.db.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

四、數(shù)據(jù)庫(kù)模型視圖

Qt中的QSqlTableModel是一個(gè)高級(jí)接口,提供了可讀可寫(xiě)的數(shù)據(jù)模型,用于在單個(gè)表中讀取和保存數(shù)據(jù),可以在QTableView展示數(shù)據(jù)庫(kù)的表格。當(dāng)連接到數(shù)據(jù)庫(kù)后,使用seTable設(shè)置要查詢的表,使用setFilter函數(shù)設(shè)置過(guò)濾器條件,然后使用select函數(shù)進(jìn)行查詢操作。可以使用setEditerStrategy函數(shù)設(shè)置編輯策略,可設(shè)置編輯策略如下:
QSqlTableModel.OnFieldChange:所有變更實(shí)時(shí)更新到數(shù)據(jù)庫(kù)
QSqlTableModel.OnRowChange:當(dāng)用戶選擇不同的行時(shí),在當(dāng)前行進(jìn)行更新
QSqlTableModel.OnManuallSubmit:手動(dòng)提交,不自動(dòng)提交

import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("/home/user/test.db")
        self.db.open()
        self.model = QSqlTableModel()
        self.initializedModel()

        self.tableView = QTableView()
        self.tableView.setModel(self.model)

        self.layout = QVBoxLayout()
        addButton = QPushButton("add")
        deleteButton = QPushButton("delete")
        hLayout = QHBoxLayout()
        hLayout.addWidget(addButton)
        hLayout.addWidget(deleteButton)
        self.layout.addWidget(self.tableView)
        self.layout.addLayout(hLayout)
        self.setLayout(self.layout)
        self.resize(600, 400)

        addButton.clicked.connect(self.onAddRow)
        deleteButton.clicked.connect(self.onDeleteRow)

    def initializedModel(self):
        self.model.setTable("person")
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.select()
        self.model.setHeaderData(0, Qt.Horizontal, "ID")
        self.model.setHeaderData(1, Qt.Horizontal, "Name")
        self.model.setHeaderData(2, Qt.Horizontal, "Address")

    def onAddRow(self):
        self.model.insertRows(self.model.rowCount(), 1)
        self.model.submit()

    def onDeleteRow(self):
        self.model.removeRow(self.tableView.currentIndex().row())
        self.model.submit()
        self.model.select()

    def closeEvent(self, event):
        self.db.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

五、分頁(yè)查詢

1、數(shù)據(jù)準(zhǔn)備

分頁(yè)使用數(shù)據(jù)為學(xué)生信息student表,可以使用SQLite命令行使用SQL語(yǔ)句插入,也可以使用Python程序創(chuàng)建表并插入數(shù)據(jù)。

db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("/home/user/test.db")
if not db.open():
    return False
query = QSqlQuery()
query.exec_("create table student(id int primary key, name varchar(20), sex varchar(8), age int);")

query.exec_("insert into student values(1, 'Bauer', 'Man', 25)")
query.exec_("insert into student values(2, 'Alex', 'Man', 24)")
query.exec_("insert into student values(3, 'Mary', 'Female', 23)")
query.exec_("insert into student values(4, 'Jack', 'Man', 25)")
query.exec_("insert into student values(5, 'xiaoming', 'Man', 24)")
query.exec_("insert into student values(6, 'xiaohong', 'Female', 23)")
query.exec_("insert into student values(7, 'xiaowang', 'Man', 25)")
query.exec_("insert into student values(8, 'xiaozhang', 'Man', 25)")
query.exec_("insert into student values(9, 'xiaoli', 'Man', 25)")
query.exec_("insert into student values(10, 'xiaohan', 'Man', 25)")

2、分頁(yè)窗口

分頁(yè)窗口包括標(biāo)簽、前一頁(yè)、后一頁(yè)、跳轉(zhuǎn)按鈕等。

import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class DataGrid(QWidget):
    def __init__(self, parent=None):
        super(DataGrid, self).__init__(parent)
        # 數(shù)據(jù)庫(kù)連接
        self.db = None
        # 布局管理器
        self.layout = QVBoxLayout()
        # 查詢模型
        self.queryModel = QSqlQueryModel()
        # 表格視圖
        self.tableView = QTableView()
        self.tableView.setModel(self.queryModel)
        #
        self.totalPageLabel = QLabel()
        self.currentPageLabel = QLabel()
        self.switchPageLineEdit = QLineEdit()
        self.prevButton = QPushButton("Prev")
        self.nextButton = QPushButton("Next")
        self.switchPageButton = QPushButton("Switch")
        self.currentPage = 0
        self.totalPage = 0
        self.totalRecordCount = 0
        self.pageRecordCount = 5

    def initUI(self):
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.layout.addWidget(self.tableView)

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.prevButton)
        hLayout.addWidget(self.nextButton)
        hLayout.addWidget(QLabel("跳轉(zhuǎn)到"))
        self.switchPageLineEdit.setFixedWidth(40)
        hLayout.addWidget(self.switchPageLineEdit)
        hLayout.addWidget(QLabel("頁(yè)"))
        hLayout.addWidget(self.switchPageButton)
        hLayout.addWidget(QLabel("當(dāng)前頁(yè):"))
        hLayout.addWidget(self.currentPageLabel)
        hLayout.addWidget(QLabel("總頁(yè)數(shù):"))
        hLayout.addWidget(self.totalPageLabel)
        hLayout.addStretch(1)

        self.layout.addLayout(hLayout)
        self.setLayout(self.layout)

        self.setWindowTitle("DataGrid")
        self.resize(600, 300)

    def closeEvent(self, event):
        self.db.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = DataGrid()
    window.initUI()
    window.show()
    sys.exit(app.exec_())

如何進(jìn)行PyQt5數(shù)據(jù)庫(kù)操作

3、分頁(yè)查詢實(shí)現(xiàn)

讀取數(shù)據(jù)庫(kù)的student表,初始化表格數(shù)據(jù)模型。

import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import re

class DataGrid(QWidget):
    def __init__(self, parent=None):
        super(DataGrid, self).__init__(parent)
        # 聲明數(shù)據(jù)庫(kù)連接
        self.db = None
        # 布局管理器
        self.layout = QVBoxLayout()
        # 查詢模型
        self.queryModel = QSqlQueryModel()
        # 表格視圖
        self.tableView = QTableView()
        self.tableView.setModel(self.queryModel)
        #
        self.totalPageLabel = QLabel()
        self.currentPageLabel = QLabel()
        self.switchPageLineEdit = QLineEdit()
        self.prevButton = QPushButton("Prev")
        self.nextButton = QPushButton("Next")
        self.switchPageButton = QPushButton("Switch")
        # 當(dāng)前頁(yè)
        self.currentPage = 1
        # 總頁(yè)數(shù)
        self.totalPage = None
        # 總記錄數(shù)
        self.totalRecordCount = None
        # 每頁(yè)記錄數(shù)
        self.pageRecordCount = 4

        self.initUI()
        self.initializedModel()
        self.setUpConnect()
        self.updateStatus()

    def initUI(self):
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.layout.addWidget(self.tableView)

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.prevButton)
        hLayout.addWidget(self.nextButton)
        hLayout.addWidget(QLabel("跳轉(zhuǎn)到"))
        self.switchPageLineEdit.setFixedWidth(40)
        hLayout.addWidget(self.switchPageLineEdit)
        hLayout.addWidget(QLabel("頁(yè)"))
        hLayout.addWidget(self.switchPageButton)
        hLayout.addWidget(QLabel("當(dāng)前頁(yè):"))
        hLayout.addWidget(self.currentPageLabel)
        hLayout.addWidget(QLabel("總頁(yè)數(shù):"))
        hLayout.addWidget(self.totalPageLabel)
        hLayout.addStretch(1)

        self.layout.addLayout(hLayout)
        self.setLayout(self.layout)

        self.setWindowTitle("DataGrid")
        self.resize(600, 300)

    def setUpConnect(self):
        self.prevButton.clicked.connect(self.onPrevPage)
        self.nextButton.clicked.connect(self.onNextPage)
        self.switchPageButton.clicked.connect(self.onSwitchPage)

    def initializedModel(self):
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("/home/user/test.db")
        if not self.db.open():
            return False
        self.queryModel.setHeaderData(0, Qt.Horizontal, "ID")
        self.queryModel.setHeaderData(1, Qt.Horizontal, "Name")
        self.queryModel.setHeaderData(2, Qt.Horizontal, "Sex")
        self.queryModel.setHeaderData(3, Qt.Horizontal, "Age")
        # 獲取表的所有記錄數(shù)
        sql = "SELECT * FROM student"
        self.queryModel.setQuery(sql, self.db)
        self.totalRecordCount = self.queryModel.rowCount()
        if self.totalRecordCount % self.pageRecordCount == 0:
            self.totalPage = self.totalRecordCount / self.pageRecordCount
        else:
            self.totalPage = int(self.totalRecordCount / self.pageRecordCount) + 1
        # 顯示第1頁(yè)
        sql = "SELECT * FROM student limit %d,%d" % (0, self.pageRecordCount)
        self.queryModel.setQuery(sql, self.db)

    def onPrevPage(self):
        self.currentPage -= 1
        limitIndex = (self.currentPage - 1) * self.pageRecordCount
        self.queryRecord(limitIndex)
        self.updateStatus()

    def onNextPage(self):
        self.currentPage += 1
        limitIndex = (self.currentPage - 1) * self.pageRecordCount
        self.queryRecord(limitIndex)
        self.updateStatus()

    def onSwitchPage(self):
        szText = self.switchPageLineEdit.text()
        pattern = re.compile('^[0-9]+$')
        match = pattern.match(szText)
        if not match:
            QMessageBox.information(self, "提示", "請(qǐng)輸入數(shù)字.")
            return
        if szText == "":
            QMessageBox.information(self, "提示", "請(qǐng)輸入跳轉(zhuǎn)頁(yè)面.")
            return
        pageIndex = int(szText)
        if pageIndex > self.totalPage or pageIndex < 1:
            QMessageBox.information(self, "提示", "沒(méi)有指定的頁(yè),清重新輸入.")
            return

        limitIndex = (pageIndex - 1) * self.pageRecordCount
        self.queryRecord(limitIndex)
        self.currentPage = pageIndex
        self.updateStatus()

    # 根據(jù)分頁(yè)查詢記錄
    def queryRecord(self, limitIndex):
        sql = "SELECT * FROM student limit %d,%d" % (limitIndex, self.pageRecordCount)
        self.queryModel.setQuery(sql)

    # 更新空間狀態(tài)
    def updateStatus(self):
        self.currentPageLabel.setText(str(self.currentPage))
        self.totalPageLabel.setText(str(self.totalPage))
        if self.currentPage <= 1:
            self.prevButton.setEnabled(False)
        else:
            self.prevButton.setEnabled(True)

        if self.currentPage >= self.totalPage:
            self.nextButton.setEnabled(False)
        else:
            self.nextButton.setEnabled(True)

    # 界面關(guān)閉時(shí)關(guān)閉數(shù)據(jù)庫(kù)連接
    def closeEvent(self, event):
        self.db.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = DataGrid()
    window.show()
    sys.exit(app.exec_())

如何進(jìn)行PyQt5數(shù)據(jù)庫(kù)操作

關(guān)于如何進(jìn)行PyQt5數(shù)據(jù)庫(kù)操作問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI