PyQt学习系列笔记(Python Qt框架)
第七课:PyQt的数据库操作与ORM集成
一、PyQt数据库操作概述
1.1 为什么需要数据库操作?
在现代桌面应用程序中,数据持久化是核心需求。PyQt通过QtSql
模块提供了对多种数据库的完整支持(如SQLite、MySQL、PostgreSQL),并结合ORM框架(如SQLAlchemy、Django ORM)可实现高效的数据管理。
核心目标:
- 连接数据库(SQLite、MySQL、PostgreSQL等)。
- 执行SQL语句(增删改查)。
- 使用数据模型类(
QSqlTableModel
、QSqlRelationalTableModel
)。 - 集成ORM框架(SQLAlchemy、Django ORM)。
二、PyQt数据库操作基础
2.1 核心类与模块
PyQt的QtSql
模块提供了以下关键类:
类名 | 功能 |
---|---|
QSqlDatabase |
管理数据库连接(添加驱动、打开/关闭连接)。 |
QSqlQuery |
执行SQL语句(查询、插入、更新、删除)。 |
QSqlTableModel |
将数据库表映射为表格模型,支持增删改查。 |
QSqlRecord |
表示数据库中的一行记录。 |
三、数据库连接
3.1 SQLite数据库连接
SQLite是轻量级嵌入式数据库,适合小型应用。
示例:连接SQLite数据库
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
def connect_sqlite():
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("example.db") # 数据库文件名
if not db.open():
print("无法打开数据库连接")
return False
print("成功连接到SQLite数据库")
return True
3.2 MySQL数据库连接
MySQL适合需要高并发和复杂查询的场景。
示例:连接MySQL数据库
def connect_mysql():
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("localhost") # 主机地址
db.setDatabaseName("mydatabase") # 数据库名
db.setUserName("username") # 用户名
db.setPassword("password") # 密码
if not db.open():
print("无法打开MySQL数据库连接")
return False
print("成功连接到MySQL数据库")
return True
四、基本数据库操作(CRUD)
4.1 创建表
使用QSqlQuery
执行SQL语句创建表。
示例:创建用户表
def create_table():
query = QSqlQuery()
sql = """
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
)
"""
if not query.exec_(sql):
print("创建表失败:", query.lastError().text())
else:
print("表创建成功")
4.2 插入数据
使用QSqlQuery
插入数据。
示例:插入用户数据
def insert_user(name, age):
query = QSqlQuery()
sql = "INSERT INTO users (name, age) VALUES (?, ?)"
query.prepare(sql)
query.addBindValue(name)
query.addBindValue(age)
if query.exec_():
print(f"用户 {name} 插入成功")
else:
print("插入数据失败:", query.lastError().text())
4.3 查询数据
使用QSqlQuery
查询数据。
示例:查询所有用户
def select_users():
query = QSqlQuery()
query.exec_("SELECT * FROM users")
while query.next():
user_id = query.value(0)
name = query.value(1)
age = query.value(2)
print(f"ID: {user_id}, Name: {name}, Age: {age}")
4.4 更新和删除数据
更新和删除操作通过SQL语句实现。
示例:更新用户年龄
def update_user_age(name, new_age):
query = QSqlQuery()
sql = "UPDATE users SET age = ? WHERE name = ?"
query.prepare(sql)
query.addBindValue(new_age)
query.addBindValue(name)
if query.exec_():
print(f"用户 {name} 年龄更新成功")
else:
print("更新数据失败:", query.lastError().text())
示例:删除用户
def delete_user(name):
query = QSqlQuery()
sql = "DELETE FROM users WHERE name = ?"
query.prepare(sql)
query.addBindValue(name)
if query.exec_():
print(f"用户 {name} 删除成功")
else:
print("删除数据失败:", query.lastError().text())
五、使用QSqlTableModel
操作数据库
5.1 显示数据到表格
QSqlTableModel
将数据库表映射为表格模型,适合与QTableView
结合使用。
示例:显示用户表
from PyQt5.QtWidgets import QTableView
from PyQt5.QtSql import QSqlTableModel
def show_table():
model = QSqlTableModel(db=QSqlDatabase.database())
model.setTable("users")
model.select() # 加载数据
view = QTableView()
view.setModel(model)
view.resizeColumnsToContents()
view.show()
5.2 编辑数据
通过QSqlTableModel
可以直接编辑表格中的数据。
示例:允许用户编辑数据
model.setEditStrategy(QSqlTableModel.OnFieldChange) # 实时保存更改
view.setModel(model)
view.show()
六、ORM框架集成
6.1 SQLAlchemy集成
SQLAlchemy是Python中流行的ORM框架,支持多种数据库。
示例:使用SQLAlchemy定义模型
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer)
# 创建数据库连接
engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
示例:通过ORM操作数据
# 插入数据
new_user = User(name='Alice', age=25)
session.add(new_user)
session.commit()
# 查询数据
users = session.query(User).all()
for user in users:
print(f"ID: {user.id}, Name: {user.name}, Age: {user.age}")
6.2 Django ORM集成
Django ORM通过模型类定义数据结构,并与PyQt结合实现数据展示。
示例:Django模型定义
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
gender = models.CharField(max_length=10)
remark_mobiles = models.CharField(max_length=20)
corp_name = models.CharField(max_length=100)
add_time = models.DateTimeField(auto_now_add=True)
示例:在PyQt中加载Django模型数据
# 假设Django模型已初始化
from myapp.models import User
def load_data_to_table():
users = User.objects.all()
for user in users:
# 将数据填充到QTableWidget中
row_position = self.tableWidget.rowCount()
self.tableWidget.insertRow(row_position)
self.tableWidget.setItem(row_position, 0, QTableWidgetItem(user.name))
self.tableWidget.setItem(row_position, 1, QTableWidgetItem(user.gender))
七、高级数据库功能
7.1 分页与搜索
通过QSqlTableModel
实现分页和搜索功能。
示例:分页显示数据
model.setFilter("id > 0") # 设置过滤条件
model.setSort(0, Qt.AscendingOrder) # 按ID升序排序
model.select()
示例:搜索特定用户
model.setFilter(f"name LIKE '%{search_text}%'")
model.select()
7.2 事务处理
事务确保多个操作的原子性。
示例:使用事务
db.transaction()
try:
query.exec_("UPDATE users SET age = 30 WHERE name = 'Alice'")
query.exec_("INSERT INTO users (name, age) VALUES ('Bob', 28)")
db.commit()
except:
db.rollback()
print("事务回滚")
八、常见问题与解决方案
8.1 数据库连接失败
原因:数据库文件不存在、驱动不支持、密码错误。
解决方法:
- 检查数据库路径是否正确。
- 确保安装了对应数据库驱动(如MySQL驱动需安装
mysqlclient
)。
8.2 SQL语句报错
原因:SQL语法错误或字段名拼写错误。
解决方法:
- 使用
query.lastError().text()
获取错误信息。 - 通过打印SQL语句调试(如
print(query.lastQuery())
)。
8.3 ORM模型映射问题
原因:ORM模型与数据库表结构不一致。
解决方法:
- 确保ORM模型的字段与数据库表匹配。
- 使用
Base.metadata.create_all(engine)
自动创建表。
九、总结与下一步
本节课重点讲解了PyQt的数据库操作与ORM集成,包括:
- 数据库连接:SQLite、MySQL、PostgreSQL的支持。
- 基本CRUD操作:使用
QSqlQuery
执行SQL语句。 - 数据模型类:
QSqlTableModel
实现表格数据绑定。 - ORM集成:SQLAlchemy和Django ORM的使用。
- 高级功能:分页、搜索、事务处理。
下节课预告:
第八课将深入讲解PyQt的多线程与异步编程,包括QThread
、QThreadPool
、asyncio
的集成,以及如何避免UI卡顿。请持续关注后续内容!
参考资料: