安装 MySQL 第三方库
要在 Python 中操作 MySQL,需要使用一个专用的第三方库 —— pymysql。
它负责完成 Python 与 MySQL 数据库之间的通信。
安装 pymysql
打开终端或命令提示符,执行:
pip install pymysql
这是连接 MySQL 所需的核心环境。
为什么需要 pymysql?
Python 本身不包含操作 MySQL 的功能,因此需要通过外部库来:
- 建立数据库连接
- 执行 SQL
- 获取查询结果
- 控制事务提交
pymysql 是最常用、最轻量的 MySQL 操作库之一。
验证是否安装成功
安装后可以尝试写一个最基础的连接脚本验证:
from pymysql import Connection
conn = Connection(
host='localhost', # 主机名或 IP
port=3306, # 端口号(默认 3306)
user='root', # MySQL 用户名
password='root' # MySQL 密码
)
print(conn.get_server_info()) # 打印 MySQL 版本
conn.close()
如果能正常输出 MySQL 版本号,说明 pymysql 已安装且数据库连接成功。
安装部分小结
- 使用
pip install pymysql完成安装 - 导入方式固定为:
from pymysql import Connection - 能否连接成功取决于:主机、端口、账号、密码是否正确,以及 MySQL 服务是否运行
- 获取版本号是常用的“连通性测试”
Python 操作 MySQL 的基本流程
使用 Python 操作 MySQL 时,通常都遵循同一个标准流程:
1. 建立数据库连接
2. 获取游标对象
3. 执行 SQL 语句(增 / 删 / 改 / 查)
4. 提交事务(对于写操作)
5. 关闭游标与连接
下面对每个步骤进行详细说明。
建立数据库连接
通过 pymysql.Connection 创建连接对象:
from pymysql import Connection
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root',
autocommit=False # 是否自动提交事务
)
说明:
- host:数据库服务器地址
- port:端口号(默认 3306)
- user:用户名
- password:密码
- autocommit:是否自动提交事务,建议关闭并手动提交
成功创建连接对象后,即可使用 conn 与 MySQL 通信。
获取游标对象(cursor)
游标相当于“执行 SQL 的工具”:
cursor = conn.cursor()
有了 cursor 才能执行 SQL 语句。
执行 SQL 语句
执行语句使用:
cursor.execute("SQL语句")
例如创建数据库:
cursor.execute("CREATE DATABASE test_db")
执行插入:
cursor.execute(
"INSERT INTO student(name, age) VALUES('tom', 18)"
)
执行查询:
cursor.execute("SELECT * FROM student")
对于写操作必须手动提交事务
写操作包括:
- INSERT
- UPDATE
- DELETE
手动提交:
conn.commit()
如果不提交,插入 / 更新 / 删除不会真正保存到数据库。
关闭游标与连接(重要)
游标与连接都是资源,不关闭会导致:
- 数据库连接占用
- 线程、进程资源消耗
- 后续无法正常再次连接
正确关闭顺序:
cursor.close()
conn.close()
完整流程示例
from pymysql import Connection
# 建立连接
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root'
)
# 创建 cursor
cursor = conn.cursor()
# 执行 SQL
cursor.execute("CREATE DATABASE demo")
# 提交事务
conn.commit()
# 关闭连接
cursor.close()
conn.close()
本章小结
| 步骤 | 说明 |
|---|---|
| 建立连接 | 使用 Connection() 连接数据库 |
| 获取游标 | cursor = conn.cursor() |
| 执行 SQL | cursor.execute() |
| 提交事务 | conn.commit()(写操作必需) |
| 关闭资源 | cursor.close() & conn.close() |
这五步构成了 Python 操作 MySQL 的标准流程,后续所有 CRUD 都基于此展开。
创建数据库与数据表
Python 通过 pymysql 的 cursor 对象执行 SQL,就可以完成数据库与数据表的创建操作。本章将以示例方式讲解完整流程。
一、创建数据库
创建数据库只需执行一条 SQL:
cursor.execute("CREATE DATABASE test_db")
完整示例:
from pymysql import Connection
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root'
)
cursor = conn.cursor()
cursor.execute("CREATE DATABASE test_db")
conn.commit()
cursor.close()
conn.close()
成功执行后,MySQL 会新增一个名为 test_db 的数据库。
选择数据库
创建完数据库后,要想在其中创建表,需要先选择数据库:
cursor.execute("USE test_db")
创建数据表
例如创建一张 student 表:
cursor.execute("""
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT
)
""")
说明:
id为主键AUTO_INCREMENT表示自增name为字符串,长度 50age为整数
完整的“创建数据库 + 创建表”示例
from pymysql import Connection
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root'
)
cursor = conn.cursor()
# 创建数据库
cursor.execute("CREATE DATABASE test_db")
# 选择数据库
cursor.execute("USE test_db")
# 创建数据表
cursor.execute("""
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT
)
""")
conn.commit()
cursor.close()
conn.close()
注意事项
- 创建数据库与表属于写操作,因此 必须 commit()
- 数据表字段定义需符合 MySQL 语法
- AUTO_INCREMENT 通常用于主键 ID
- USE 语句用于切换当前操作数据库
- 字段类型应根据业务选取,例如:VARCHAR、INT、FLOAT、DATETIME 等
本章小结
| 操作 | SQL 示例 |
|---|---|
| 创建数据库 | CREATE DATABASE test_db |
| 选择数据库 | USE test_db |
| 创建表 | CREATE TABLE student (...) |
| 提交事务 | conn.commit() |
数据插入(INSERT)
向 MySQL 写入数据是最常见的操作之一。Python 使用 cursor.execute() 执行 SQL,即可完成 INSERT。
插入数据有:
- 单条数据插入
- 批量数据插入
- 获取自增 ID
- 手动提交事务的重要性
下面依次讲解。
单条数据插入
最基础的插入方式:
cursor.execute("INSERT INTO student(name, age) VALUES('Tom', 18)")
conn.commit()
注意:
- INSERT 属于写操作 → 必须 commit(),否则不会真正写入数据库。
完整示例
from pymysql import Connection
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root'
)
cursor = conn.cursor()
cursor.execute("USE test_db")
cursor.execute("INSERT INTO student(name, age) VALUES('Tom', 18)")
conn.commit()
cursor.close()
conn.close()
插入数据时的引号问题
字符串值必须加单引号:
'Tom'
数字不需要加引号:
18
拼接字符串时必须注意 SQL 注入风险(后面章节会讲)。
获取自增 ID
MySQL 支持 ID 自动增长,我们可以在插入后获取新纪录的 ID:
cursor.execute("INSERT INTO student(name, age) VALUES('Jack', 20)")
conn.commit()
new_id = cursor.lastrowid
print("新插入数据的 ID:", new_id)
好处:
- 用于获取新用户、新订单、新日志等主键
- 在多表写入时需要使用新 ID 拼接其他 SQL
批量插入(executemany)
当你需要一次性插入大量数据时,使用 executemany 效率更高。
示例:
data = [
("Alice", 19),
("Bob", 20),
("Cindy", 18)
]
cursor.executemany(
"INSERT INTO student(name, age) VALUES(%s, %s)",
data
)
conn.commit()
说明:
%s是 pymysql 的占位符- executemany 会对每条数据执行一次插入
- 比循环 execute 更高效
使用参数化插入(避免 SQL 注入)
推荐使用占位符 + 参数,而不是字符串拼接。
sql = "INSERT INTO student(name, age) VALUES(%s, %s)"
cursor.execute(sql, ("Tom", 18))
conn.commit()
优点:
- 更安全
- 自动处理引号与转义
- 避免 SQL 注入
这是生产环境最常用的写法。
插入多条记录(循环方式)
不建议大量数据使用 for 循环,但少量数据可以:
students = [("张三", 18), ("李四", 19), ("王五", 20)]
for stu in students:
cursor.execute(sql, stu)
conn.commit()
本章小结
| 插入方式 | 说明 |
|---|---|
| execute() | 插入单条数据 |
| executemany() | 插入多条数据(高效) |
| lastrowid | 获取自增 ID |
| commit() | 写操作必须提交 |
| 参数化插入 | 安全且推荐的生产写法 |
一句话总结:
INSERT 操作的关键是:占位符写法、提交事务、合理使用 executemany。
数据查询(SELECT)
对数据库的数据进行查询,是应用开发中最常见的操作之一。
Python 通过 cursor.execute() 执行 SELECT,再用 fetchone / fetchall 获取结果。
本章将讲解:
- 基础查询
- 单条查询
- 多条查询
- 遍历查询结果
- 条件查询
- 排序与限制(LIMIT)
执行查询 SQL
最基础的写法:
cursor.execute("SELECT * FROM student")
此时,数据已经被读取到游标中,但还没有取出,需要使用 fetch 系列方法。
获取一条记录:fetchone()
result = cursor.fetchone()
print(result)
返回值示例:
(1, 'Tom', 18)
说明:
- 返回一个 tuple,顺序与字段一致
- 多次执行 fetchone,会依次取下一条记录
- 若无更多数据 → 返回 None
获取所有记录:fetchall()
result = cursor.fetchall()
print(result)
返回:
[
(1, 'Tom', 18),
(2, 'Jack', 20),
(3, 'Alice', 19)
]
fetchall 适合数据量不大时的一次性获取。
遍历查询结果
fetchall 的结果可以直接使用 for 遍历:
cursor.execute("SELECT * FROM student")
results = cursor.fetchall()
for row in results:
print(row[0], row[1], row[2])
或者更清晰的写法:
for stu_id, name, age in results:
print(stu_id, name, age)
条件查询(WHERE)
示例:查询 age 大于 18 的学生:
cursor.execute("SELECT * FROM student WHERE age > 18")
rows = cursor.fetchall()
示例:查询 name=’Tom’:
cursor.execute("SELECT * FROM student WHERE name = %s", ("Tom",))
注意:
- 使用占位符可以避免 SQL 注入
- (“Tom”,) 必须是元组
排序查询(ORDER BY)
按 age 从小到大排序:
cursor.execute("SELECT * FROM student ORDER BY age ASC")
从大到小:
cursor.execute("SELECT * FROM student ORDER BY age DESC")
限制查询数量(LIMIT)
只查询前 3 条:
cursor.execute("SELECT * FROM student LIMIT 3")
分页示例:
cursor.execute("SELECT * FROM student LIMIT 3 OFFSET 3")
或简写:
cursor.execute("SELECT * FROM student LIMIT 3, 3")
条件 + 排序 + 限制 综合示例
cursor.execute("""
SELECT *
FROM student
WHERE age >= 18
ORDER BY age DESC
LIMIT 5
""")
for row in cursor.fetchall():
print(row)
本章小结
| 查询方法 | 说明 |
|---|---|
| fetchone() | 获取一条记录 |
| fetchall() | 获取所有记录 |
| execute() + WHERE | 条件查询 |
| ORDER BY | 按字段排序 |
| LIMIT | 限制数量,分页常用 |
一句话总结:
SELECT 的本质是执行 SQL → 再通过 fetch 取出结果。
数据更新与删除(UPDATE / DELETE)
数据修改与数据删除都是数据库的写操作,需要:
- 使用
cursor.execute()执行 SQL - 使用
conn.commit()提交事务 - 查看
cursor.rowcount获取受影响行数
下面详细说明。
数据更新(UPDATE)
基本语法:
UPDATE 表名 SET 字段=值 WHERE 条件;
示例:把 Tom 的 age 更新为 20:
cursor.execute(
"UPDATE student SET age = 20 WHERE name = %s",
("Tom",)
)
conn.commit()
说明:
- UPDATE 必须带 WHERE,否则会影响整张表
- 使用占位符传参能防止 SQL 注入
查看受影响行数:rowcount
执行更新后,可以查看 rowcount:
print(cursor.rowcount)
可能输出:
1 → 修改成功一条数据
0 → 未找到匹配的数据
这在业务判断中非常有用。
删除数据(DELETE)
语法:
DELETE FROM 表名 WHERE 条件;
示例:删除 name 为 Jack 的记录:
cursor.execute(
"DELETE FROM student WHERE name = %s",
("Jack",)
)
conn.commit()
与 UPDATE 相同:
- DELETE 也必须带 WHERE
- 否则会清空整张表(非常危险)
完整示例:更新 + 删除
from pymysql import Connection
conn = Connection(
host='localhost',
port=3306,
user='root',
password='root'
)
cursor = conn.cursor()
cursor.execute("USE test_db")
# 更新
cursor.execute(
"UPDATE student SET age = %s WHERE name = %s",
(21, "Tom")
)
print("更新行数:", cursor.rowcount)
# 删除
cursor.execute(
"DELETE FROM student WHERE age < %s",
(18,)
)
print("删除行数:", cursor.rowcount)
conn.commit()
cursor.close()
conn.close()
commit() 的重要性
UPDATE 与 DELETE 都属于写操作,必须执行:
conn.commit()
否则数据库不会保存修改。
本章小结
| 操作 | SQL 示例 | 注意事项 |
|---|---|---|
| UPDATE | UPDATE student SET age=20 WHERE id=1 | 必须带 WHERE |
| DELETE | DELETE FROM student WHERE age<18 | 必须带 WHERE |
| rowcount | cursor.rowcount | 获取受影响行数 |
| commit | conn.commit() | 写操作必须提交 |
一句话总结:
UPDATE 与 DELETE 的关键:带 WHERE、执行 commit、查看 rowcount。
事务处理(Transaction)
事务是数据库保证数据安全性与一致性的关键机制,尤其在涉及多条 SQL 的业务逻辑中,事务能确保:
要么全部成功,要么全部失败。
在 Python 中通过 pymysql 操作 MySQL 时,需要手动控制事务,如提交、回滚等。
事务的四大特性(ACID)
事务必须满足以下 4 点:
- 原子性(Atomicity)
整个事务要么全部成功,要么全部失败,中途不允许部分成功。 - 一致性(Consistency)
事务前后,数据库必须保持一致状态。 - 隔离性(Isolation)
各事务之间相互独立,不会互相干扰。 - 持久性(Durability)
提交事务后,数据必须被永久保存。
Python 操作 MySQL 重点关注:
原子性(提交 / 回滚)。
自动提交 autocommit(不推荐)
Connection 默认可设置 autocommit:
conn = Connection(..., autocommit=True)
缺点:
- 每执行一次 SQL 自动提交
- 无法保证多条 SQL 的原子性
因此生产环境通常:
autocommit=False # 手动提交
手动提交事务 commit()
用于写操作成功时保存数据:
conn.commit()
如果不 commit:
- INSERT、UPDATE、DELETE 不会真正保存
- 查询不到更新的内容
回滚事务 rollback()
如果某个 SQL 执行出错,可回滚到执行前的状态:
conn.rollback()
作用:
- 撤销所有未提交的操作
- 保证不会出现“部分成功,部分失败”的脏数据
事务的标准写法(异常处理 + 回滚)
这是生产环境标准模板:
from pymysql import Connection
conn = Connection(
host="localhost",
port=3306,
user="root",
password="root",
autocommit=False
)
cursor = conn.cursor()
cursor.execute("USE test_db")
try:
cursor.execute("UPDATE student SET age=30 WHERE id=1")
cursor.execute("UPDATE student SET age=18 WHERE id=2")
conn.commit() # 所有 SQL 运行成功 → 提交
print("事务提交成功")
except Exception as e:
print("发生错误,事务回滚:", e)
conn.rollback() # 出现错误 → 回滚
finally:
cursor.close()
conn.close()
事务使用场景示例
● 场景 1:多表写入(例如创建订单 + 写入订单明细)
若明细失败而主记录成功,会导致脏数据,必须使用事务。
● 场景 2:转账(A 转 B)
典型事务操作示例:
扣 A 的钱
加 B 的钱
任意一步失败 → 回滚
● 场景 3:批量更新
多条更新必须保证全部成功,否则保持原样。
本章小结
| 操作 | 说明 |
|---|---|
| commit() | 提交事务,保存数据 |
| rollback() | 回滚事务,撤销未提交操作 |
| autocommit=False | 手动控制事务,推荐 |
| try / except / finally | 事务控制最佳实践 |
一句话总结:
所有写数据库的逻辑都应该包裹在事务中,错误时回滚,成功时提交,这是数据安全的底线。
Python 操作 MySQL 综合案例
本章通过一个完整的业务流程演示如何使用 Python + pymysql 操作 MySQL,包含:
- 建立连接
- 建库建表
- 插入数据
- 查询数据
- 更新与删除
- 事务处理
- 输出最终结果
这是掌握 MySQL 读写流程最重要的一章。
准备数据库连接对象
from pymysql import Connection
conn = Connection(
host="localhost",
port=3306,
user="root",
password="root",
autocommit=False
)
cursor = conn.cursor()
创建数据库与数据表
cursor.execute("CREATE DATABASE IF NOT EXISTS test_db")
cursor.execute("USE test_db")
cursor.execute("""
CREATE TABLE IF NOT EXISTS student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT
)
""")
conn.commit()
插入数据(两种方式:单条 / 批量)
方式一:单条插入
cursor.execute(
"INSERT INTO student(name, age) VALUES(%s, %s)",
("Tom", 18)
)
方式二:批量插入
data = [
("Jack", 20),
("Alice", 19),
("Cindy", 22)
]
cursor.executemany(
"INSERT INTO student(name, age) VALUES(%s, %s)",
data
)
conn.commit()
查询数据(fetchone / fetchall)
cursor.execute("SELECT * FROM student")
rows = cursor.fetchall()
for row in rows:
print(row)
示例输出:
(1, 'Tom', 18)
(2, 'Jack', 20)
(3, 'Alice', 19)
(4, 'Cindy', 22)
更新数据
cursor.execute(
"UPDATE student SET age=%s WHERE name=%s",
(30, "Tom")
)
print("影响行数:", cursor.rowcount)
conn.commit()
六、删除数据
cursor.execute(
"DELETE FROM student WHERE age < %s",
(20,)
)
print("影响行数:", cursor.rowcount)
conn.commit()
事务处理(保证操作的原子性)
try:
cursor.execute(
"UPDATE student SET age=50 WHERE name=%s",
("Alice",)
)
cursor.execute(
"UPDATE student SET age=10 WHERE name=%s",
("Cindy",)
)
conn.commit()
print("事务提交成功")
except Exception as e:
print("发生异常,事务回滚:", e)
conn.rollback()
完整案例代码(可直接复制运行)
from pymysql import Connection
conn = Connection(
host="localhost",
port=3306,
user="root",
password="root",
autocommit=False
)
cursor = conn.cursor()
# 1. 建库建表
cursor.execute("CREATE DATABASE IF NOT EXISTS test_db")
cursor.execute("USE test_db")
cursor.execute("""
CREATE TABLE IF NOT EXISTS student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT
)
""")
conn.commit()
# 2. 插入数据
cursor.execute(
"INSERT INTO student(name, age) VALUES(%s, %s)",
("Tom", 18)
)
data = [("Jack", 20), ("Alice", 19), ("Cindy", 22)]
cursor.executemany(
"INSERT INTO student(name, age) VALUES(%s, %s)", data
)
conn.commit()
# 3. 查询数据
cursor.execute("SELECT * FROM student")
for row in cursor.fetchall():
print(row)
# 4. 更新数据
cursor.execute(
"UPDATE student SET age=%s WHERE name=%s",
(30, "Tom")
)
conn.commit()
# 5. 删除数据
cursor.execute(
"DELETE FROM student WHERE age < %s",
(20,)
)
conn.commit()
# 6. 事务处理示例
try:
cursor.execute("UPDATE student SET age=50 WHERE name=%s", ("Alice",))
cursor.execute("UPDATE student SET age=10 WHERE name=%s", ("Cindy",))
conn.commit()
except Exception as e:
print("事务回滚:", e)
conn.rollback()
cursor.close()
conn.close()
本章总结
| 功能 | 涉及的 SQL / 方法 |
|---|---|
| 建库建表 | CREATE DATABASE / CREATE TABLE |
| 插入 | INSERT / executemany / lastrowid |
| 查询 | SELECT / fetchall / fetchone |
| 更新删除 | UPDATE / DELETE / rowcount |
| 事务 | commit / rollback / try-except |
一句话总结:
本章示例覆盖了 Python 操作 MySQL 的全部关键能力,学会此案例即可独立进行 CRUD 与事务开发。