一、mysqlclient 库核心介绍
mysqlclient 是 Python 中用于连接和操作 MySQL 数据库的高性能驱动库,它基于 MySQL C API 开发,是 Django 官方推荐的 MySQL 适配驱动。其工作原理是通过底层 C 语言接口与 MySQL 服务器建立通信,实现 SQL 语句的执行、数据的增删改查等操作。

该库的优点十分突出:运行速度快,相比纯 Python 实现的驱动效率更高;兼容性好,支持 Python 3.x 系列版本和主流 MySQL 服务器版本;与 Django、SQLAlchemy 等主流框架无缝集成。缺点则是安装时对系统环境有一定要求,Windows 系统需提前配置 Visual C++ 编译工具,Linux 系统需安装 libmysqlclient-dev 依赖库。
mysqlclient 的开源协议为 GPLv2,用户可自由使用、修改和分发,但修改后的衍生作品需遵循相同协议。以上内容整体控制在200字内,精准覆盖库的核心用途、原理、优缺点及协议类型。
二、mysqlclient 安装步骤
针对不同操作系统,mysqlclient 的安装方式略有差异,下面分别介绍 Windows、Linux、macOS 三大平台的安装流程,确保技术小白也能顺利完成配置。
2.1 前置依赖安装
- Windows 系统
由于 mysqlclient 依赖 MySQL C API,Windows 系统需提前安装 Microsoft Visual C++ 14.0 或更高版本。安装时勾选“Desktop development with C++”组件,完成后重启电脑。
若不想配置编译环境,可直接从 Unofficial Windows Binaries for Python Packages 下载对应 Python 版本和系统位数的whl包,例如 Python 3.10 64位系统选择mysqlclient‑2.2.4‑cp310‑cp310‑win_amd64.whl。 - Linux 系统
Ubuntu/Debian 系列执行以下命令安装依赖:
sudo apt-get update
sudo apt-get install libmysqlclient-dev python3-dev
CentOS/RHEL 系列执行:
sudo yum install mysql-community-devel python3-devel
- macOS 系统
需先安装 Xcode 命令行工具和 Homebrew,再执行:
xcode-select --install
brew install mysql-connector-c
2.2 使用 pip 安装 mysqlclient
当前置依赖配置完成后,打开命令行工具,执行统一的 pip 安装命令:
pip install mysqlclient
若下载过慢,可使用国内镜像源加速:
pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple
安装成功后,在 Python 交互环境中执行 import MySQLdb,若没有报错,则说明安装完成。
三、mysqlclient 核心使用方法
mysqlclient 提供的核心模块是 MySQLdb,通过该模块可以建立数据库连接、创建游标对象、执行 SQL 语句、处理查询结果。下面通过具体实例,详细讲解每一步的操作方法。
3.1 建立数据库连接
使用 MySQLdb.connect() 方法创建数据库连接对象,该方法的常用参数如下:
| 参数名 | 作用 | 示例值 |
|–||–|
| host | MySQL 服务器地址 | “localhost” |
| user | 数据库用户名 | “root” |
| passwd | 数据库密码 | “123456” |
| db | 要连接的数据库名 | “test_db” |
| port | MySQL 服务端口号 | 3306 |
| charset | 字符编码 | “utf8mb4” |
实例代码:
import MySQLdb
# 建立数据库连接
try:
conn = MySQLdb.connect(
host="localhost",
user="root",
passwd="123456",
db="test_db",
port=3306,
charset="utf8mb4"
)
print("数据库连接成功!")
except MySQLdb.Error as e:
print(f"数据库连接失败:{e}")
代码说明:
- 导入
MySQLdb模块,这是使用 mysqlclient 的前提。 - 使用
try-except语句捕获连接过程中可能出现的异常,例如密码错误、数据库不存在等。 - 连接成功后会返回一个连接对象
conn,后续所有操作都基于该对象展开。
3.2 创建游标对象
游标对象是执行 SQL 语句的载体,通过连接对象的 cursor() 方法创建:
# 创建游标对象
cursor = conn.cursor()
游标对象提供了 execute()、fetchone()、fetchall() 等方法,用于执行 SQL 和获取结果。
3.3 执行 SQL 语句
mysqlclient 支持执行所有标准 SQL 语句,包括创建表、插入数据、查询数据、更新数据、删除数据等,下面分别演示不同场景的操作。
3.3.1 创建数据表
以创建一个 student 表为例,表中包含 id(主键自增)、name(姓名)、age(年龄)、gender(性别)、score(分数)字段。
实例代码:
# 定义创建表的 SQL 语句
create_sql = """
CREATE TABLE IF NOT EXISTS student (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT,
gender ENUM('男', '女', '未知'),
score FLOAT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
try:
# 执行 SQL 语句
cursor.execute(create_sql)
print("数据表创建成功!")
except MySQLdb.Error as e:
print(f"数据表创建失败:{e}")
代码说明:
- 定义多行 SQL 语句时,使用三引号包裹,确保语句格式清晰。
IF NOT EXISTS关键字用于避免重复创建表导致的报错。- 通过
cursor.execute()方法执行 SQL 语句,该方法接收 SQL 字符串作为参数。
3.3.2 插入数据
插入数据分为单条插入和批量插入两种方式,批量插入可以有效减少与数据库的交互次数,提升效率。
单条数据插入
# 定义插入单条数据的 SQL 语句
insert_sql = "INSERT INTO student(name, age, gender, score) VALUES (%s, %s, %s, %s)"
data = ("张三", 18, "男", 92.5)
try:
# 执行插入操作
cursor.execute(insert_sql, data)
# 提交事务
conn.commit()
print(f"插入成功,影响行数:{cursor.rowcount}")
except MySQLdb.Error as e:
# 发生错误时回滚事务
conn.rollback()
print(f"插入失败:{e}")
代码说明:
- SQL 语句中使用
%s作为占位符,避免直接拼接字符串导致的 SQL 注入风险,这是 mysqlclient 推荐的参数传递方式。 cursor.execute()的第二个参数是一个元组,元组中的元素与占位符一一对应。- 执行插入、更新、删除等写操作后,必须调用
conn.commit()提交事务,否则数据不会真正写入数据库;若发生错误,需调用conn.rollback()回滚事务,撤销已执行的操作。 cursor.rowcount属性可以获取 SQL 语句执行后影响的行数。
批量数据插入
# 定义批量插入的 SQL 语句
batch_insert_sql = "INSERT INTO student(name, age, gender, score) VALUES (%s, %s, %s, %s)"
# 准备多条数据
batch_data = [
("李四", 19, "男", 88.0),
("王五", 17, "女", 95.0),
("赵六", 18, "男", 79.5)
]
try:
# 执行批量插入,使用 executemany 方法
cursor.executemany(batch_insert_sql, batch_data)
conn.commit()
print(f"批量插入成功,影响行数:{cursor.rowcount}")
except MySQLdb.Error as e:
conn.rollback()
print(f"批量插入失败:{e}")
代码说明:
批量插入使用 cursor.executemany() 方法,第一个参数是 SQL 语句,第二个参数是包含多个元组的列表,每个元组对应一条数据。该方法比多次调用 execute() 效率更高,适合插入大量数据的场景。
3.3.3 查询数据
查询数据是数据库操作中最常用的场景,mysqlclient 提供了 fetchone()、fetchmany()、fetchall() 三种方法获取查询结果。
查询所有数据
# 定义查询 SQL 语句
select_sql = "SELECT * FROM student"
try:
cursor.execute(select_sql)
# 获取所有查询结果
results = cursor.fetchall()
# 遍历结果
for row in results:
student_id = row[0]
name = row[1]
age = row[2]
gender = row[3]
score = row[4]
print(f"ID: {student_id}, 姓名: {name}, 年龄: {age}, 性别: {gender}, 分数: {score}")
except MySQLdb.Error as e:
print(f"查询失败:{e}")
代码说明:
cursor.fetchall()方法会获取查询结果集中的所有数据,返回一个包含元组的列表,每个元组对应一行数据。- 通过索引可以访问元组中的每个字段,索引顺序与 SQL 查询的字段顺序一致。
查询单条数据
# 查询分数大于90的第一条数据
select_one_sql = "SELECT * FROM student WHERE score > 90 LIMIT 1"
try:
cursor.execute(select_one_sql)
result = cursor.fetchone()
if result:
print(f"高分学生:姓名{result[1]}, 分数{result[4]}")
else:
print("未找到符合条件的数据")
except MySQLdb.Error as e:
print(f"查询失败:{e}")
代码说明:cursor.fetchone() 方法每次只获取结果集中的一行数据,返回一个元组;若没有更多数据,则返回 None。该方法适合只需要获取一条数据的场景,例如查询用户登录信息。
查询指定条数数据
# 查询前2条数据
select_many_sql = "SELECT * FROM student"
try:
cursor.execute(select_many_sql)
results = cursor.fetchmany(2)
for row in results:
print(f"姓名: {row[1]}, 年龄: {row[2]}")
except MySQLdb.Error as e:
print(f"查询失败:{e}")
代码说明:cursor.fetchmany(size) 方法可以指定获取的行数,参数 size 为要获取的条数,返回一个包含元组的列表;若结果集中的剩余数据不足 size 条,则返回剩余所有数据。
3.3.4 更新数据
更新数据的操作流程与插入数据类似,执行 UPDATE 语句后需要提交事务。
实例代码:
# 定义更新 SQL 语句,将张三的分数更新为95
update_sql = "UPDATE student SET score = %s WHERE name = %s"
update_data = (95, "张三")
try:
cursor.execute(update_sql, update_data)
conn.commit()
print(f"更新成功,影响行数:{cursor.rowcount}")
except MySQLdb.Error as e:
conn.rollback()
print(f"更新失败:{e}")
3.3.5 删除数据
删除数据时建议添加条件,避免误删全表数据,执行 DELETE 语句后同样需要提交事务。
实例代码:
# 定义删除 SQL 语句,删除年龄小于18的学生
delete_sql = "DELETE FROM student WHERE age < %s"
delete_data = (18,)
try:
cursor.execute(delete_sql, delete_data)
conn.commit()
print(f"删除成功,影响行数:{cursor.rowcount}")
except MySQLdb.Error as e:
conn.rollback()
print(f"删除失败:{e}")
3.4 关闭游标和连接
数据库操作完成后,需要依次关闭游标和连接,释放资源,避免占用过多服务器连接数。
实例代码:
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
print("数据库连接已关闭")
代码说明:
关闭顺序必须是先关闭游标,再关闭连接,否则会导致资源释放不彻底。
四、实际应用案例:学生成绩管理系统
为了让大家更好地掌握 mysqlclient 的综合使用,下面搭建一个简单的学生成绩管理系统,实现添加学生、查询所有学生、根据姓名查询学生、修改学生分数、删除学生五个核心功能。
4.1 系统功能实现代码
import MySQLdb
class StudentScoreSystem:
def __init__(self, host, user, passwd, db, port=3306, charset="utf8mb4"):
"""初始化数据库连接"""
self.host = host
self.user = user
self.passwd = passwd
self.db = db
self.port = port
self.charset = charset
self.conn = None
self.cursor = None
self.connect_db()
def connect_db(self):
"""建立数据库连接"""
try:
self.conn = MySQLdb.connect(
host=self.host,
user=self.user,
passwd=self.passwd,
db=self.db,
port=self.port,
charset=self.charset
)
self.cursor = self.conn.cursor()
print("数据库连接成功")
except MySQLdb.Error as e:
print(f"数据库连接失败:{e}")
def add_student(self, name, age, gender, score):
"""添加学生信息"""
sql = "INSERT INTO student(name, age, gender, score) VALUES (%s, %s, %s, %s)"
data = (name, age, gender, score)
try:
self.cursor.execute(sql, data)
self.conn.commit()
print(f"添加学生 {name} 成功")
except MySQLdb.Error as e:
self.conn.rollback()
print(f"添加学生失败:{e}")
def query_all_students(self):
"""查询所有学生信息"""
sql = "SELECT * FROM student"
try:
self.cursor.execute(sql)
results = self.cursor.fetchall()
if not results:
print("暂无学生数据")
return
print("所有学生信息:")
for row in results:
print(f"ID: {row[0]}, 姓名: {row[1]}, 年龄: {row[2]}, 性别: {row[3]}, 分数: {row[4]}")
except MySQLdb.Error as e:
print(f"查询失败:{e}")
def query_student_by_name(self, name):
"""根据姓名查询学生信息"""
sql = "SELECT * FROM student WHERE name = %s"
data = (name,)
try:
self.cursor.execute(sql, data)
result = self.cursor.fetchone()
if result:
print(f"查询结果:ID: {result[0]}, 姓名: {result[1]}, 年龄: {result[2]}, 性别: {result[3]}, 分数: {result[4]}")
else:
print(f"未找到姓名为 {name} 的学生")
except MySQLdb.Error as e:
print(f"查询失败:{e}")
def update_student_score(self, name, new_score):
"""修改学生分数"""
sql = "UPDATE student SET score = %s WHERE name = %s"
data = (new_score, name)
try:
self.cursor.execute(sql, data)
self.conn.commit()
if self.cursor.rowcount > 0:
print(f"修改 {name} 的分数为 {new_score} 成功")
else:
print(f"未找到姓名为 {name} 的学生")
except MySQLdb.Error as e:
self.conn.rollback()
print(f"修改分数失败:{e}")
def delete_student(self, name):
"""删除学生信息"""
sql = "DELETE FROM student WHERE name = %s"
data = (name,)
try:
self.cursor.execute(sql, data)
self.conn.commit()
if self.cursor.rowcount > 0:
print(f"删除学生 {name} 成功")
else:
print(f"未找到姓名为 {name} 的学生")
except MySQLdb.Error as e:
self.conn.rollback()
print(f"删除学生失败:{e}")
def close(self):
"""关闭游标和连接"""
self.cursor.close()
self.conn.close()
print("数据库连接已关闭")
# 系统使用示例
if __name__ == "__main__":
# 初始化系统,替换为自己的数据库信息
system = StudentScoreSystem(
host="localhost",
user="root",
passwd="123456",
db="test_db"
)
# 添加学生
system.add_student("张三", 18, "男", 90)
system.add_student("李四", 19, "女", 92)
# 查询所有学生
system.query_all_students()
# 根据姓名查询
system.query_student_by_name("张三")
# 修改分数
system.update_student_score("张三", 95)
# 删除学生
system.delete_student("李四")
# 再次查询所有学生
system.query_all_students()
# 关闭连接
system.close()
4.2 代码说明
- 该案例采用面向对象的编程思想,将数据库操作封装成一个类
StudentScoreSystem,提高代码的可复用性和可维护性。 __init__方法在创建类实例时自动执行,完成数据库连接的初始化。- 每个功能对应一个方法,例如
add_student负责添加学生,query_student_by_name负责根据姓名查询,方法内部都包含了异常处理和事务管理。 if __name__ == "__main__"代码块用于测试系统功能,实际使用时可以根据需要调用不同的方法。
五、相关资源地址
- Pypi地址:https://pypi.org/project/mysqlclient
- Github地址:https://github.com/PyMySQL/mysqlclient
- 官方文档地址:https://mysqlclient.readthedocs.io/
关注我,每天分享一个实用的Python自动化工具。

