Python连接MySQL新手指南:安装pymysql与执行基础查询
本教程详细讲解如何使用纯Python驱动PyMySQL连接MySQL数据库,涵盖驱动安装、连接建立、游标使用、SELECT基础查询、数据遍历、INSERT事务提交、防御SQL注入与连接资源管理等核心操作。
在 Python 开发中,与关系型数据库进行通信是一项核心基础能力。本文面向初学者,系统演示如何使用纯 Python 驱动库 PyMySQL 建立与 MySQL 数据库的连接,执行基础的数据查询(SELECT)与插入(INSERT),并在操作中遵循资源自动释放与防范 SQL 注入的安全开发规范。
一、核心架构与准备工作
在编写代码之前,需要明确 Python 程序与 MySQL 之间的通信机制。Python 本身并不内置 MySQL 的底层网络协议支持,因此必须通过“数据库驱动”(Driver)来充当两者之间的翻译官。PyMySQL 是一个完全由 Python 语言编写的轻量级驱动,遵循 Python 官方的 DB-API 2.0 规范,不需要在操作系统中预装复杂的 C 语言依赖库或编译工具,非常适合开发调试与跨平台部署。
开始前,请确保满足以下基础环境:
- Python 解释器:Python 3.7 及以上版本(建议使用虚拟环境
venv进行隔离管理)。 - MySQL 服务端:MySQL 5.7 或 8.0 服务已正常启动,且具备监听端口(默认 3306)。
- 测试用户与数据库:拥有可访问的主机地址、用户名、密码以及已创建的测试库(例如名为
test_db)。
二、安装与验证 PyMySQL
在操作系统的终端(Terminal 或命令提示符)中,通过 Python 的包管理器 pip 进行安装:
pip install pymysql
安装完成后,在终端中启动 Python 交互式环境,执行以下命令以验证安装状态与版本号:
python -c "import pymysql; print('PyMySQL 安装成功,版本号:', pymysql.__version__)"
若屏幕输出版本号(例如 1.1.0),说明驱动已就绪且可以在脚本中正常导入使用。
三、建立数据库连接的全过程
连接 MySQL 时,核心入口是 pymysql.connect() 方法。我们需要向其传递数据库的主机地址、端口号、认证凭据以及基础通信编码。
以下是连接 MySQL 的关键参数表:
| 参数名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
host |
str | MySQL 服务的 IP 地址或域名 | '127.0.0.1' 或 'localhost' |
port |
int | MySQL 服务的监听端口(注意必须为整数) | 3306 |
user |
str | 登录数据库的用户名 | 'root' |
password |
str | 登录密码 | '123456' |
database |
str | 连接后默认选中的数据库名称 | 'test_db' |
charset |
str | 通信字符集,强烈建议使用 'utf8mb4' |
'utf8mb4' |
cursorclass |
Class | 游标返回格式,默认为元组,可指定为字典游标 | pymysql.cursors.DictCursor |
MySQL 中的 utf8 编码实现并不完整(最多只支持 3 字节字符),遇到 Emoji 表情或生僻字时会直接抛出错误。始终在连接参数中显式指定 charset='utf8mb4'。
四、执行基础查询(SELECT)与游标操作
在数据库操作中,游标(Cursor)是一个核心抽象概念。可以把它想象为一个“工作指针”和“数据缓冲区”。当 SQL 发送到数据库后,MySQL 会生成结果集,而游标负责保存当前遍历位置并按需把数据行读取到 Python 内存中。
1. 完整查询示例(使用上下文管理器)
在实际编码中,强烈建议使用 Python 的 with 上下文管理器来管理 connection 和 cursor,无论程序发生正常返回还是异常报错,上下文管理器均能确保底层网络连接被正确释放:
import pymysql
import pymysql.cursors
# 1. 建立数据库连接
connection = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='your_password',
database='test_db',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor # 输出为字典格式
)
try:
with connection.cursor() as cursor:
# 2. 准备 SQL 语句并执行
sql = "SELECT id, name, email, age FROM users WHERE age >= %s"
cursor.execute(sql, (18,))
# 3. 获取所有符合条件的记录
results = cursor.fetchall()
print(f"查询成功,共匹配到 {len(results)} 条记录:")
for row in results:
print(f"ID: {row['id']} | 姓名: {row['name']} | 年龄: {row['age']} | 邮箱: {row['email']}")
finally:
# 4. 关闭物理连接
connection.close()
print("数据库连接已安全关闭。")
运行结果示例:
查询成功,共匹配到 2 条记录:
ID: 1 | 姓名: 张三 | 年龄: 24 | 邮箱: zhangsan@example.com
ID: 2 | 姓名: 李四 | 年龄: 28 | 邮箱: lisi@example.com
数据库连接已安全关闭。
五、写入数据与事务提交(INSERT 与 commit)
在进行基础查询(SELECT)时,我们只需要读取数据;但对于写入操作(INSERT、UPDATE、DELETE),MySQL 默认在事务模式下工作。如果执行了 cursor.execute() 插入记录,但未显式调用 connection.commit(),在脚本退出后,所做的修改将会被数据库回滚,导致表中并未写入任何数据。
import pymysql
connection = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='your_password',
database='test_db',
charset='utf8mb4'
)
try:
with connection.cursor() as cursor:
insert_sql = "INSERT INTO users (name, email, age) VALUES (%s, %s, %s)"
cursor.execute(insert_sql, ('王五', 'wangwu@example.com', 22))
# 核心:必须调用 commit() 显式提交事务
connection.commit()
print(f"数据插入成功,受影响行数: {cursor.rowcount},新增主键 ID: {cursor.lastrowid}")
except Exception as error:
# 发生异常时回滚未提交的事务
connection.rollback()
print(f"插入数据失败,事务已回滚: {error}")
finally:
connection.close()
六、安全防线:使用参数化查询防范 SQL 注入
新手最常犯的一个危险错误是使用 Python 的字符串拼接(如 + 号拼接或 f-string)来组装 SQL 语句。这会导致严重的 SQL 注入漏洞。PyMySQL 提供了内置的参数化占位符 %s,驱动层会自动对输入变量进行转义和类型校验,杜绝恶意 SQL 代码执行。
绝对禁止的危险拼接写法:
user_input = "zhangsan' OR '1'='1"sql = f"SELECT * FROM users WHERE name = '{user_input}'" # 危险!将被注入
唯一推荐的参数化写法:
sql = "SELECT * FROM users WHERE name = %s"cursor.execute(sql, (user_input,)) # 安全!驱动会自动进行严格转义
七、新手常见报错与排查指南
在初次连接与查询数据库时,经常会遇到以下几类常见错误,可以按照以下诊断逻辑逐项排查:
八、全文总结
通过本文的讲解与实践,我们掌握了 Python 连接并操作 MySQL 的基本工作流:
- 驱动选用:选用纯 Python 实现的
PyMySQL能够极大简化安装和跨平台部署复杂度。 - 规范连接:连接必须指定
charset='utf8mb4'确保字符完全兼容,推荐使用DictCursor游标提升代码可读性。 - 游标调度:
execute()负责指令通信,fetchone()或fetchall()负责按需读取结果数据。 - 事务控制:对数据库内容产生实质修改的语句(INSERT/UPDATE/DELETE)必须显式
connection.commit()。 - 安全防御:严禁使用字符串拼接组装 SQL,必须始终使用参数化占位符
%s,保障数据库远离 SQL 注入风险。 - 资源管理:务必使用
with上下文管理器或在finally块中调用close()释放游标与网络连接。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









