在Python里操作MySQL数据库,核心是通过数据库驱动建立连接、创建游标、执行SQL语句并处理结果。目前最常用的是pymysql这个第三方库,它是纯Python实现,兼容Python3,安装和使用都比较简单。相比旧的MySQLdb,它不需要系统层编译,跨平台更友好。

一、环境准备与安装
在开始写代码前,需要先准备好MySQL服务并安装pymysql库。确保你的机器上已经运行了MySQL服务器,并且知道用户名、密码、主机地址和要操作的数据库名。如果是本地开发,通常主机是127.0.0.1,端口是3306。
使用pip命令即可安装pymysql,不需要额外依赖。在终端或命令行中执行下面指令:
pip install pymysql
安装完成后,可以在Python交互环境中导入验证是否成功。如果没有报错,说明库已经就绪。建议同时用MySQL客户端创建一个测试库,例如test_db,方便后面运行示例代码。
二、建立连接与基本查询
连接MySQL的第一步是调用pymysql.connect方法,传入必要的参数。这些方法参数包括host、user、password、database以及字符集等。建立连接后,需要通过连接对象拿到游标,再由游标执行SQL。
下面是一段最基础的查询示例,连接到本地MySQL并读取一张用户表的数据:
import pymysql
# 建立数据库连接
conn = pymysql.connect(
host='127.0.0.1',
user='root',
password='your_password',
database='test_db',
charset='utf8mb4'
)
try:
# 创建游标,返回字典类型结果
with conn.cursor(pymysql.cursors.DictCursor) as cursor:
sql = 'SELECT id, name FROM users LIMIT 5'
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print(row)
finally:
conn.close()
上面代码使用了with语句管理游标,确保游标用完自动关闭。在最外层用try/finally保证连接一定会被关闭,避免连接泄漏。如果查询量较大,可以用fetchone或fetchmany控制内存占用。
需要注意的是,pymysql默认不会自动提交事务。对于SELECT语句没有影响,但如果是写操作就必须显式调用conn.commit,否则数据不会真正落库。这一点在后面会详细说。
三、插入与更新操作的注意事项
写操作例如INSERT、UPDATE、DELETE都需要在执行后提交事务。很多初学者写完代码发现数据库里没有数据,就是因为漏了commit。下面演示安全的插入方式,使用参数化查询防止SQL注入。
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
user='root',
password='your_password',
database='test_db',
charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
# 参数化插入,占位符为%s
sql = 'INSERT INTO users (name, age) VALUES (%s, %s)'
cursor.execute(sql, ('张三', 28))
# 提交事务
conn.commit()
except Exception as e:
# 出错回滚
conn.rollback()
print('插入失败:', e)
finally:
conn.close()
参数化查询通过execute的第二个参数传入元组,pymysql会自动转义特殊字符,避免拼接字符串带来的注入风险。千万不要用字符串格式化拼SQL,例如'INSERT INTO users VALUES (%s)' % name这种写法非常危险。
如果一次要插入多行,可以使用executemany方法,它比循环execute更高效,同样支持参数化。更新和删除操作写法类似,只是SQL语句不同,但都不要忘记commit或rollback。
四、事务与连接管理的最佳实践
在真实项目中,频繁打开关闭连接会拖慢性能,也容易产生太多未关闭的连接。可以使用连接池,例如dbutils配合pymysql,或者直接用框架自带的数据层。简单脚本里至少应该用with管理连接生命周期。
下面展示用上下文管理器封装连接的写法,让代码更干净,也能保证异常时自动回滚和关闭:
import pymysql
from contextlib import contextmanager
@contextmanager
def mysql_conn():
conn = pymysql.connect(
host='127.0.0.1',
user='root',
password='your_password',
database='test_db',
charset='utf8mb4'
)
try:
yield conn
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
# 使用方式
with mysql_conn() as conn:
with conn.cursor() as cursor:
cursor.execute('UPDATE users SET age=%s WHERE name=%s', (30, '张三'))
这种写法把提交和回滚逻辑集中在管理器里,业务代码只需要关注SQL本身。当嵌套with退出时,如果没有异常就提交,有异常就回滚,连接也必定关闭。
对于Web应用,推荐把连接池配置放在全局,每次请求从池里取连接,用完归还。这样既能支撑并发,又不会把MySQL的最大连接数打满。同时设置连接超时和回收时间,防止用到失效连接。
五、常见错误与排查思路
操作MySQL时经常遇到几类报错。比如Access denied说明账号密码或权限不对;Can't connect说明地址端口或防火墙问题;Character set报错一般是建表和服务端编码不一致。看异常信息大多能定位。
还有一个隐蔽问题是游标类型。默认游标返回元组,若想要字典方便取值,要传cursors.DictCursor。另外执行DDL比如建表语句不需要commit,但最好别在业务代码里乱建表。遇到死锁或超时,可以查MySQL的慢查询日志和进程列表。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 插入后查不到数据 | 未调用commit | 执行后conn.commit() |
| 报编码错误 | charset不匹配 | 统一用utf8mb4 |
| 连接数爆满 | 连接未关闭 | 用with或连接池 |
掌握上面这些内容,你就能用Python稳定地操作MySQL,完成日常的数据读写、统计和简单运维任务。后续可以结合ORM如SQLAlchemy进一步提升开发效率,但理解底层驱动依然十分重要。