Python中怎样使用pymysql连接和操作MySQL数据库?

来源:苹果APP网作者:孙悟空头衔:草根站长
导读:本期聚焦于小伙伴创作的《Python中怎样使用pymysql连接和操作MySQL数据库?》,敬请观看详情。不少新手在写Python脚本时卡在了数据库环节,明明装了MySQL却连不上。pymysql作为纯Python实现的驱动,不依赖系统库,用pip就能装好。它提供Connection与Cursor两类核心对象,先建连接再拿游标执行SQL,最后提交或回滚。比起旧版MySQLdb,它在Python3下更省心,也避开了编译扩展的麻烦。本文从安装、建立连接、增删改查到防注入与连接池,把常见用法一次讲清,帮你少踩超时和编码的坑。

在Python生态里操作MySQL,pymysql是最常被选用的纯Python驱动之一。它不依赖任何C扩展,兼容Python3各个版本,安装和使用都比较轻量。理解它的工作模型,核心就是先拿到一个连接对象,再基于连接创建游标,通过游标发送SQL并取回结果。

Python中怎样使用pymysql连接和操作MySQL数据库?

一、安装与基础连接

使用pymysql的第一步是安装包。因为它已发布到PyPI,直接用pip即可完成,不需要本机安装MySQL开发头文件。在虚拟环境中安装可以避免污染全局Python。

pip install pymysql

建立连接时,需要明确主机、端口、用户、密码和库名。下面是一段最基础的连接代码,其中设置了字符集为utf8mb4,避免中文写入变成问号。

import pymysql

# 创建连接
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4'
)

# 使用完记得关闭
conn.close()

上面代码在脚本结束前手动关闭了连接。实际项目中更推荐用with语句管理生命周期,这样即使中间抛异常也能保证连接释放,减少MySQL服务端连接数被占满的风险。

二、执行查询与增删改

连接建立后,要通过cursor对象执行SQL。pymysql默认游标返回的是元组,若想用字典方式按字段名取值,可指定DictCursor。下面的例子演示了查询和插入两种典型操作。

import pymysql
from pymysql.cursors import DictCursor

conn = pymysql.connect(
    host='127.0.0.1',
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4'
)

try:
    with conn.cursor(DictCursor) as cursor:
        # 查询
        cursor.execute('SELECT id, name FROM users WHERE age > %s', (18,))
        rows = cursor.fetchall()
        for row in rows:
            print(row['name'])

        # 插入
        sql = 'INSERT INTO users(name, age) VALUES(%s, %s)'
        cursor.execute(sql, ('张三', 20))
    conn.commit()
except Exception as e:
    conn.rollback()
    print('出错回滚:', e)
finally:
    conn.close()

注意增删改操作必须调用conn.commit()才能真正落库,这是MySQL事务引擎的要求。如果忘记提交,程序退出后改动会丢失。遇到异常时应当rollback,防止产生半成品数据。

参数化查询里用的%s不是Python字符串格式化,而是pymysql的占位符,它会在底层做转义,有效防止SQL注入。千万不要用字符串拼接拼SQL,否则用户输入单引号就能篡改语义。

三、批量操作与防注入

当需要写入大量数据时,逐条execute效率很低。pymysql提供了executemany,可以在一次网络往返里发送多组参数,显著提升吞吐。

import pymysql

conn = pymysql.connect(host='127.0.0.1', user='root', password='your_password', database='test_db')
with conn.cursor() as cursor:
    data = [('李四', 22), ('王五', 25), ('赵六', 19)]
    cursor.executemany('INSERT INTO users(name, age) VALUES(%s, %s)', data)
conn.commit()
conn.close()

防注入方面,除了坚持参数化,还应避免把表名和字段名用参数传进去,因为占位符只适用于值。如果表名动态变化,应在白名单中校验后再拼入SQL,且绝不可来自用户直接输入。

另外,从外部读取的CSV或接口数据,可能包含特殊字符,pymysql会自动转义单引号和反斜杠,但开发者仍需确认charset设置一致,否则可能出现乱码导致语句解析异常。

四、连接池与异常处理

短连接频繁创建销毁会带来明显开销。虽然pymysql本身不带连接池,但可结合DBUtils等库实现。以下示例展示用PersistentDB维持每个线程独立连接。

from dbutils.persistent_db import PersistentDB
import pymysql

pool = PersistentDB(
    creator=pymysql,
    maxusage=1000,
    host='127.0.0.1',
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4'
)

conn = pool.connection()
try:
    with conn.cursor() as cur:
        cur.execute('SELECT 1')
        print(cur.fetchone())
finally:
    conn.close()

异常处理上,应捕获pymysql.err.OperationalError来区分连接超时、认证失败等不同情况。对于临时性网络抖动,可加重试逻辑;对于认证错误,重试无意义,应直接告警。

合理设置connect_timeout和read_timeout也能避免脚本卡死。在Web服务中,把连接池大小控制在数据库最大连接数的七成以内,可留余地给运维命令使用。

五、常见坑与排查思路

编码问题是高频坑。若数据库是utf8mb4而连接用了utf8,写入emoji会报错。统一charset为utf8mb4最稳妥。其次是时区,MySQL的time_zone若与程序所在机器不一致,时间字段会出现偏差,可在连接串加init_command设置。

conn = pymysql.connect(
    host='127.0.0.1',
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4',
    init_command="SET time_zone='+08:00'"
)

还有一种是游标未关闭导致内存占用高。fetchall一次性拉全表在大数据量时会撑爆内存,应改成分页fetchmany或服务端游标。遇到Commands out of sync错误,通常是上一条查询的结果集没读完就执行新命令,需确保先消费完再继续。

掌握上述用法后,Python配合pymysql处理日常MySQL任务已经足够。后续可进一步了解事务隔离级别和慢查询日志,把数据层做得更稳。

pymysqlPython_MySQL数据库连接修改时间:2026-08-08 18:33:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。