news 2026/9/12 10:10:54

Python3使用PyMySQL操作MySQL数据库全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python3使用PyMySQL操作MySQL数据库全指南

1. Python3与MySQL数据库交互基础

PyMySQL是Python3中用于连接MySQL数据库的纯Python实现库,它完全遵循Python DB API 2.0规范。与MySQLdb相比,PyMySQL不需要编译安装,兼容性更好,特别适合Python3环境。

1.1 环境准备与安装

在开始使用PyMySQL之前,需要确保已安装Python3和MySQL数据库。推荐使用Python 3.6+和MySQL 5.7+/8.0版本组合,这是目前最稳定的搭配。

安装PyMySQL非常简单,使用pip命令即可:

pip install PyMySQL

对于需要特定版本的情况,可以指定版本号:

pip install PyMySQL==1.0.2

注意:如果同时安装了MySQLdb和PyMySQL,建议优先使用PyMySQL,因为它在Python3中的支持更好,且维护更活跃。

1.2 基本连接配置

建立数据库连接是操作MySQL的第一步,以下是基本连接示例:

import pymysql # 建立数据库连接 connection = pymysql.connect( host='localhost', # 数据库服务器地址 user='username', # 数据库用户名 password='password', # 数据库密码 database='test_db', # 数据库名 port=3306, # MySQL默认端口 charset='utf8mb4', # 字符编码 cursorclass=pymysql.cursors.DictCursor # 设置返回字典格式的结果 ) try: with connection.cursor() as cursor: # 执行SQL查询 sql = "SELECT * FROM users WHERE id = %s" cursor.execute(sql, (1,)) # 获取查询结果 result = cursor.fetchone() print(result) finally: # 关闭连接 connection.close()

连接参数说明:

  • host: MySQL服务器地址,本地可以使用'localhost'或'127.0.0.1'
  • user: 数据库用户名
  • password: 对应用户的密码
  • database: 要连接的数据库名称
  • port: MySQL服务端口,默认3306
  • charset: 字符集编码,推荐使用'utf8mb4'以支持完整的Unicode字符
  • cursorclass: 设置游标类型,DictCursor会返回字典形式的结果

2. 数据库基本操作详解

2.1 创建表操作

使用PyMySQL执行DDL语句创建表:

def create_table(): connection = pymysql.connect(host='localhost', user='user', password='passwd', database='test_db', charset='utf8mb4') try: with connection.cursor() as cursor: # 创建users表 sql = """ CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci """ cursor.execute(sql) # 提交事务 connection.commit() finally: connection.close()

表设计注意事项:

  1. 主键通常使用自增INT类型
  2. 字符串字段明确指定字符集和排序规则
  3. 重要的字段添加NOT NULL约束
  4. 唯一性字段添加UNIQUE约束
  5. 时间戳字段设置合适的默认值

2.2 数据插入操作

插入数据是数据库操作的基础,PyMySQL提供了多种插入方式:

def insert_data(): connection = pymysql.connect(...) # 连接参数同上 try: with connection.cursor() as cursor: # 单条插入 sql = "INSERT INTO users (username, email) VALUES (%s, %s)" cursor.execute(sql, ('user1', 'user1@example.com')) # 批量插入 users = [ ('user2', 'user2@example.com'), ('user3', 'user3@example.com'), ('user4', 'user4@example.com') ] cursor.executemany(sql, users) connection.commit() except pymysql.err.IntegrityError as e: print(f"插入数据失败: {e}") connection.rollback() finally: connection.close()

插入数据时的最佳实践:

  1. 始终使用参数化查询(%s占位符)而非字符串拼接,防止SQL注入
  2. 批量操作使用executemany()提高效率
  3. 处理可能的异常,如唯一键冲突(IntegrityError)
  4. 操作完成后及时提交或回滚事务

2.3 数据查询操作

PyMySQL提供了多种数据查询和结果获取方式:

def query_data(): connection = pymysql.connect(...) try: with connection.cursor() as cursor: # 基本查询 cursor.execute("SELECT * FROM users WHERE username LIKE %s", ('user%',)) # 获取所有结果 all_results = cursor.fetchall() print("所有结果:", all_results) # 获取单条结果 cursor.execute("SELECT * FROM users WHERE id = %s", (1,)) one_result = cursor.fetchone() print("单条结果:", one_result) # 分批获取结果 cursor.execute("SELECT * FROM users") while True: batch = cursor.fetchmany(size=2) # 每次获取2条 if not batch: break print("批次结果:", batch) finally: connection.close()

查询结果处理技巧:

  1. fetchall()返回所有结果,适合小数据量
  2. fetchone()获取单条结果,常用于精确查询
  3. fetchmany(size)分批获取,适合大数据量处理
  4. 游标会保持状态,可以多次执行不同查询

3. 高级功能与性能优化

3.1 事务处理

MySQL的事务特性对于数据一致性至关重要:

def transfer_money(from_id, to_id, amount): connection = pymysql.connect(...) try: with connection.cursor() as cursor: # 检查转出账户余额 cursor.execute("SELECT balance FROM accounts WHERE id = %s FOR UPDATE", (from_id,)) from_balance = cursor.fetchone()['balance'] if from_balance < amount: raise ValueError("余额不足") # 扣减转出账户 cursor.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", (amount, from_id)) # 增加转入账户 cursor.execute("UPDATE accounts SET balance = balance + %s WHERE id = %s", (amount, to_id)) connection.commit() except Exception as e: connection.rollback() print(f"转账失败: {e}") finally: connection.close()

事务处理要点:

  1. 使用FOR UPDATE锁定要修改的行,防止并发修改
  2. 在try块中执行所有数据库操作
  3. 成功时提交(commit),失败时回滚(rollback)
  4. 确保在finally中关闭连接

3.2 连接池管理

对于高并发应用,使用连接池可以显著提高性能:

from dbutils.pooled_db import PooledDB # 创建连接池 pool = PooledDB( creator=pymysql, maxconnections=10, # 最大连接数 mincached=2, # 初始化时创建的连接数 host='localhost', user='user', password='passwd', database='test_db', charset='utf8mb4' ) def query_with_pool(): # 从连接池获取连接 connection = pool.connection() try: with connection.cursor() as cursor: cursor.execute("SELECT * FROM users") results = cursor.fetchall() return results finally: # 将连接返回连接池而非关闭 connection.close()

连接池配置建议:

  1. maxconnections根据应用负载调整,通常10-50
  2. mincached设置初始连接数,减少首次请求延迟
  3. 使用后调用connection.close()将连接返回到池中
  4. 考虑使用连接池管理工具如SQLAlchemy

3.3 预处理语句与性能

预处理语句可以提高性能并防止SQL注入:

def prepared_statement(): connection = pymysql.connect(...) try: with connection.cursor() as cursor: # 创建预处理语句 stmt = "INSERT INTO logs (user_id, action) VALUES (%s, %s)" # 批量执行 actions = [ (1, 'login'), (2, 'view_page'), (3, 'logout') ] cursor.executemany(stmt, actions) connection.commit() finally: connection.close()

性能优化技巧:

  1. 对于重复执行的SQL,使用预处理语句
  2. 批量操作使用executemany()
  3. 合理使用索引提高查询效率
  4. 考虑使用存储过程处理复杂逻辑

4. 常见问题与解决方案

4.1 连接问题排查

常见连接错误及解决方法:

  1. 错误2003 (HY000): Can't connect to MySQL server

    • 检查MySQL服务是否运行
    • 确认连接参数(host, port)正确
    • 检查防火墙设置
  2. 错误1045 (28000): Access denied

    • 确认用户名密码正确
    • 检查用户是否有远程连接权限
    • MySQL8.0+可能需要使用新的认证插件
  3. 错误2013 (HY000): Lost connection

    • 增加连接超时时间:connect_timeout=10
    • 检查网络稳定性
    • 可能是服务器端超时设置过短

连接参数调整示例:

connection = pymysql.connect( host='localhost', user='user', password='passwd', database='test_db', connect_timeout=10, # 连接超时时间(秒) read_timeout=30, # 读取超时时间 write_timeout=30 # 写入超时时间 )

4.2 字符编码问题

MySQL字符集常见问题处理:

  1. 乱码问题

    • 确保连接指定charset='utf8mb4'
    • 检查表/字段字符集设置
    • Python3字符串处理使用unicode
  2. emoji存储问题

    • 必须使用utf8mb4字符集
    • 修改表字段定义:
      ALTER TABLE messages MODIFY content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  3. 排序规则问题

    • 中文排序使用utf8mb4_unicode_ci
    • 区分大小写使用utf8mb4_bin

4.3 数据类型映射

Python与MySQL数据类型对应关系:

Python类型MySQL类型注意事项
intINT, BIGINT注意整数范围
floatFLOAT, DOUBLE精度问题需注意
strVARCHAR, TEXT长度限制和字符集很重要
bytesBLOB, BINARY适合存储二进制数据
datetime.datetimeDATETIME, TIMESTAMP时区处理要小心
boolTINYINT(1)MySQL没有真正的布尔类型

类型处理示例:

def type_handling(): connection = pymysql.connect(...) try: with connection.cursor() as cursor: # 处理各种数据类型 data = { 'name': '张三', # str -> VARCHAR 'age': 30, # int -> INT 'score': 89.5, # float -> FLOAT 'is_active': True, # bool -> TINYINT(1) 'birthday': datetime.date(1990, 5, 15), # date -> DATE 'created_at': datetime.datetime.now() # datetime -> DATETIME } sql = """INSERT INTO people (name, age, score, is_active, birthday, created_at) VALUES (%(name)s, %(age)s, %(score)s, %(is_active)s, %(birthday)s, %(created_at)s)""" cursor.execute(sql, data) connection.commit() finally: connection.close()

4.4 连接池最佳实践

生产环境连接池配置建议:

  1. 大小设置

    • 连接池大小 = (核心数 * 2) + 有效磁盘数
    • 通常8-50之间,根据负载测试调整
  2. 连接验证

    • 设置ping=1自动验证连接有效性
    • 配置连接最大存活时间
  3. 完整配置示例

pool = PooledDB( creator=pymysql, maxconnections=20, mincached=5, maxcached=10, maxusage=100, # 单个连接最大使用次数 blocking=True, # 达到最大连接数时阻塞而非报错 host='localhost', user='user', password='passwd', database='test_db', charset='utf8mb4', ping=1 # 每次使用前ping服务器检查连接 )

在实际项目中,PyMySQL与MySQL的交互远不止基本的CRUD操作。掌握连接管理、事务处理、性能优化等高级特性,才能构建健壮的数据库应用。根据具体场景合理选择方案,比如简单应用直接使用PyMySQL,复杂应用可以考虑集成SQLAlchemy等ORM工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 10:09:10

C++享元模式:内存优化与高效对象管理

1. 享元模式核心概念解析享元模式&#xff08;Flyweight Pattern&#xff09;是一种用于优化内存使用的结构型设计模式&#xff0c;特别适合处理需要创建大量相似对象的场景。这个模式的精髓在于区分对象的"内在状态"和"外在状态"&#xff0c;通过共享内在…

作者头像 李华
网站建设 2026/9/12 10:07:17

使用impress.js构建智能3D棱柱演示器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 10:06:49

Java HashMap核心原理与性能优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 10:05:38

YooAsset:Unity资源管理的工程化思维框架与热更新实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华