Python3 模块精讲:pymysql(第三方)- 连接 MySQL

一、引言:为什么 pymysql 是 Python 操作 MySQL 的首选

在 Python 后端开发、数据分析、自动化运维等场景中,MySQL 是最常用的关系型数据库 ,而 pymysql 作为纯 Python 实现的 MySQL 客户端库,无需依赖 MySQL C 语言库,跨平台兼容性强、安装便捷、API 简洁易用,已成为 Python 操作 MySQL 的标准第三方库

1.1 背景与意义

  • 纯 Python 实现,兼容 Python 3.6+ 所有版本,支持 MySQL 5.5+、8.0+ 全版本
  • 替代老旧的 MySQLdb,解决 Python3 兼容性问题,是 Django、Flask 等框架的底层依赖
  • 支持事务、存储过程、批量操作、连接池等企业级特性,满足生产环境需求
  • 轻量高效,单线程并发场景性能优异,学习成本低,适合新手入门与实战开发

据统计,超过 80% 的 Python MySQL 项目使用 pymysql,其生态完善、文档丰富,是后端开发者必须掌握的核心模块。

1.2 本章结构概览

plaintext

复制代码
📊 模块介绍 → 安装配置 → 基础连接 → 核心操作 → 高级特性 → 实战案例 → 最佳实践 → 常见问题 → 总结展望

二、核心概念解析

2.1 基本定义

概念一:pymysql 核心特性

表格

特性 说明 应用场景
纯 Python 实现 无 C 依赖,跨平台 Windows/Linux/Mac 全场景使用
兼容 MySQL 协议 支持 5.5/5.7/8.0 全版本 新旧项目无缝迁移
完整 CRUD 支持 增删改查原生支持 常规业务数据操作
事务管理 提交 / 回滚 / 保存点 金融、订单等强一致性场景
连接池适配 兼容 DBUtils 连接池 高并发 Web 服务
数据类型映射 自动转换 Python/MySQL 类型 简化数据处理
概念二:MySQL 基础连接要素
  • 主机(host) :MySQL 服务地址,本地为 localhost/127.0.0.1,远程为服务器 IP
  • 端口(port) :MySQL 默认端口 3306
  • 用户名(user) :数据库登录账号,如 root
  • 密码(password):数据库登录密码
  • 数据库名(database):要操作的目标数据库
  • 字符集(charset) :推荐 utf8mb4,支持 emoji 与全字符集

2.2 关键术语解释

  • 连接对象(Connection):Python 与 MySQL 建立的通信通道,所有操作基于此对象
  • 游标对象(Cursor):执行 SQL 语句、获取结果集的工具,类似操作手柄
  • 事务(Transaction):一组 SQL 操作的原子性单元,要么全部执行,要么全部回滚
  • 上下文管理器(with):自动管理连接 / 游标关闭,避免资源泄漏
  • 参数化查询:防止 SQL 注入的安全查询方式,核心生产环境必用

2.3 技术架构概览

plaintext

复制代码
┌─────────────────────────────────────────┐
│              应用层 (Python)             │
│          业务代码 + 调用 pymysql         │
├─────────────────────────────────────────┤
│              pymysql 核心层              │
│    连接管理 + 游标操作 + 协议解析         │
├─────────────────────────────────────────┤
│              MySQL 服务层                │
│        数据库实例 + 数据表 + 数据         │
└─────────────────────────────────────────┘

三、技术原理深入

3.1 核心技术原理

pymysql 基于 MySQL 原生通信协议 实现,通过 TCP 套接字与 MySQL 服务建立连接,将 Python 代码转换为 MySQL 可识别的 SQL 语句,再将返回结果解析为 Python 数据类型(字典、列表、元组)。

技术一:连接流程原理
  1. Python 调用 pymysql.connect() 发起 TCP 连接请求
  2. MySQL 服务验证身份(用户名 / 密码)
  3. 认证通过后建立连接通道,返回连接对象
  4. 通过连接对象创建游标,执行 SQL 语句
  5. MySQL 执行 SQL 并返回结果,pymysql 解析结果
  6. 操作完成后关闭游标与连接,释放资源
技术二:游标工作原理
  • 默认游标(Cursor):返回元组格式结果集
  • 字典游标(DictCursor):返回字典格式结果集,字段名作为 key,更易用
  • 游标执行 execute() 发送 SQL,fetchone()/fetchall() 获取数据
  • 游标占用 MySQL 资源,使用后必须关闭

3.2 数据交互机制

流程一:基础数据交互流程

plaintext

复制代码
用户调用 → 建立连接 → 创建游标 → 执行 SQL → 获取结果 → 提交/回滚 → 关闭游标 → 关闭连接
流程二:安全参数化查询流程
  1. 编写带占位符 %s 的 SQL 模板(不是 Python 格式化
  2. 将参数以元组形式传入 execute()
  3. pymysql 自动转义参数,防止 SQL 注入
  4. 发送安全 SQL 到 MySQL 执行

3.3 性能优化策略

表格

优化方向 具体方法 效果
连接复用 使用连接池,避免频繁创建 / 关闭连接 提升 50%+ 执行效率
批量操作 使用 executemany() 替代循环 execute() 减少 80% 网络开销
结果获取 按需 fetchone(),避免全量 fetchall() 降低内存占用
事务优化 批量操作包裹事务,减少自动提交 提升写入速度
字符集 固定使用 utf8mb4,避免编码转换 减少报错与性能损耗

四、安装与基础配置

4.1 安装 pymysql

bash

运行

bash 复制代码
# 标准安装(最新稳定版)
pip install pymysql

# 指定版本安装
pip install pymysql==1.1.0

# 国内镜像加速安装
pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple

4.2 安装验证

python

运行

复制代码
# 验证安装成功
import pymysql

# 打印版本号
print("pymysql 版本:", pymysql.__version__)

输出示例pymysql 版本:1.1.0

4.3 MySQL 环境准备

  1. 启动 MySQL 服务,确保端口 3306 开放
  2. 创建测试数据库:

sql

sql 复制代码
CREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. 创建测试用户(可选):

sql

sql 复制代码
CREATE USER 'test_user'@'%' IDENTIFIED BY 'Test@123456';
GRANT ALL ON test_db.* TO 'test_user'@'%';
FLUSH PRIVILEGES;

五、基础连接实战(核心代码)

5.1 最基础连接(无异常处理)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

# 数据库连接配置(核心参数)
db_config = {
    "host": "127.0.0.1",    # 本地地址,远程填服务器IP
    "port": 3306,           # MySQL默认端口
    "user": "root",         # 用户名
    "password": "你的密码", # 数据库密码
    "database": "test_db",  # 目标数据库
    "charset": "utf8mb4"    # 字符集,必须写utf8mb4
}

# 1. 建立数据库连接
conn = pymysql.connect(**db_config)

# 2. 创建游标对象(默认元组游标)
cursor = conn.cursor()

print("✅ 连接成功,游标创建完成")

# 3. 关闭游标
cursor.close()
# 4. 关闭连接
conn.close()

print("✅ 游标与连接已关闭")

5.2 带异常处理的安全连接(生产必备)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql
from pymysql import err

# 数据库配置
db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 安全连接函数
def safe_mysql_connect():
    try:
        # 建立连接
        conn = pymysql.connect(**db_config)
        print("✅ 数据库连接成功")
        
        # 创建游标
        cursor = conn.cursor()
        print("✅ 游标创建成功")
        
        return conn, cursor
    
    # 捕获连接错误
    except err.OperationalError as e:
        print(f"❌ 连接失败:用户名/密码错误或服务未启动 → {e}")
        return None, None
    
    # 捕获数据库不存在错误
    except err.ProgrammingError as e:
        print(f"❌ 数据库不存在 → {e}")
        return None, None
    
    # 其他未知错误
    except Exception as e:
        print(f"❌ 未知错误 → {e}")
        return None, None

# 调用连接
conn, cursor = safe_mysql_connect()

# 资源释放
if cursor:
    cursor.close()
if conn:
    conn.close()
    print("✅ 资源已释放")

5.3 上下文管理器连接(自动关闭,推荐)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

# 配置
db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# with 语句自动管理连接/游标,无需手动关闭
def connect_with_context():
    try:
        # 建立连接
        with pymysql.connect(**db_config) as conn:
            print("✅ 连接成功")
            
            # 创建字典游标(返回字典格式,更易用)
            with conn.cursor(pymysql.cursors.DictCursor) as cursor:
                print("✅ 字典游标创建成功")
                return True
    
    except Exception as e:
        print(f"❌ 连接失败:{e}")
        return False

# 执行
connect_with_context()

5.4 远程 MySQL 连接

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

# 远程数据库配置
remote_db_config = {
    "host": "47.xxx.xxx.xxx",  # 远程服务器公网IP
    "port": 3306,
    "user": "remote_user",
    "password": "Remote@123",
    "database": "test_db",
    "charset": "utf8mb4",
    "connect_timeout": 5  # 连接超时时间(秒)
}

# 连接远程数据库
def connect_remote_mysql():
    try:
        conn = pymysql.connect(**remote_db_config)
        print("✅ 远程 MySQL 连接成功")
        return conn
    except Exception as e:
        print(f"❌ 远程连接失败:{e}")
        return None

# 调用
conn = connect_remote_mysql()
if conn:
    conn.close()

六、核心 CURD 操作实战

6.1 创建数据表

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

# 配置
db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 创建用户表
def create_user_table():
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    # SQL 语句:创建用户表
    create_sql = """
    CREATE TABLE IF NOT EXISTS user (
        id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
        username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
        password VARCHAR(32) NOT NULL COMMENT '密码',
        age TINYINT UNSIGNED DEFAULT 0 COMMENT '年龄',
        gender ENUM('男','女','未知') DEFAULT '未知' COMMENT '性别',
        create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
        update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
    ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COMMENT = '用户信息表';
    """
    
    try:
        # 执行 SQL
        cursor.execute(create_sql)
        print("✅ 数据表创建成功")
    except Exception as e:
        print(f"❌ 创建表失败:{e}")
    finally:
        # 释放资源
        cursor.close()
        conn.close()

# 执行创建
create_user_table()

6.2 插入数据(单条 / 批量)

单条插入(参数化,防注入)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 单条插入
def insert_one_user(username, password, age, gender):
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    # 参数化 SQL(%s 是占位符,不是 Python 格式化)
    insert_sql = """
    INSERT INTO user (username, password, age, gender) 
    VALUES (%s, %s, %s, %s);
    """
    
    try:
        # 执行插入,参数以元组传入
        cursor.execute(insert_sql, (username, password, age, gender))
        # 提交事务(必须!否则数据不生效)
        conn.commit()
        print(f"✅ 插入成功,影响行数:{cursor.rowcount}")
    except Exception as e:
        # 回滚事务
        conn.rollback()
        print(f"❌ 插入失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 调用
insert_one_user("zhangsan", "123456", 22, "男")
insert_one_user("lisi", "654321", 25, "女")
批量插入(高效)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 批量插入
def insert_many_users(user_list):
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    insert_sql = """
    INSERT INTO user (username, password, age, gender) 
    VALUES (%s, %s, %s, %s);
    """
    
    try:
        # 批量执行,效率远高于循环 execute
        cursor.executemany(insert_sql, user_list)
        conn.commit()
        print(f"✅ 批量插入成功,总条数:{cursor.rowcount}")
    except Exception as e:
        conn.rollback()
        print(f"❌ 批量插入失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 测试数据
user_list = [
    ("wangwu", "111111", 23, "男"),
    ("zhaoliu", "222222", 24, "女"),
    ("sunqi", "333333", 21, "未知")
]

# 调用
insert_many_users(user_list)

6.3 查询数据

查询单条数据

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 查询单条
def get_one_user(user_id):
    conn = pymysql.connect(**db_config)
    # 直接使用字典游标
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    query_sql = "SELECT * FROM user WHERE id = %s;"
    
    try:
        cursor.execute(query_sql, (user_id,))
        # 获取一条结果
        user = cursor.fetchone()
        print("✅ 查询到用户:", user)
        return user
    except Exception as e:
        print(f"❌ 查询失败:{e}")
        return None
    finally:
        cursor.close()
        conn.close()

# 调用
get_one_user(1)
查询多条 / 全部数据

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 查询全部用户
def get_all_users():
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    query_sql = "SELECT id, username, age, gender, create_time FROM user ORDER BY id DESC;"
    
    try:
        cursor.execute(query_sql)
        # 获取所有结果
        user_list = cursor.fetchall()
        print(f"✅ 共查询到 {len(user_list)} 条用户")
        for user in user_list:
            print(user)
        return user_list
    except Exception as e:
        print(f"❌ 查询失败:{e}")
        return []
    finally:
        cursor.close()
        conn.close()

# 调用
get_all_users()

6.4 更新数据

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 更新用户年龄
def update_user_age(user_id, new_age):
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    update_sql = "UPDATE user SET age = %s WHERE id = %s;"
    
    try:
        cursor.execute(update_sql, (new_age, user_id))
        conn.commit()
        print(f"✅ 更新成功,影响行数:{cursor.rowcount}")
    except Exception as e:
        conn.rollback()
        print(f"❌ 更新失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 调用
update_user_age(1, 23)

6.5 删除数据

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 删除用户
def delete_user(user_id):
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    delete_sql = "DELETE FROM user WHERE id = %s;"
    
    try:
        cursor.execute(delete_sql, (user_id,))
        conn.commit()
        print(f"✅ 删除成功,影响行数:{cursor.rowcount}")
    except Exception as e:
        conn.rollback()
        print(f"❌ 删除失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 调用
delete_user(5)

七、高级特性实战

7.1 事务管理(保存点)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 带保存点的事务
def transaction_with_savepoint():
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    try:
        # 第一步操作
        cursor.execute("INSERT INTO user (username, password) VALUES ('test1', '123');")
        # 创建保存点
        conn.savepoint("sp1")
        
        # 第二步操作
        cursor.execute("INSERT INTO user (username, password) VALUES ('test2', '456');")
        
        # 回滚到保存点(撤销第二步,保留第一步)
        conn.rollback("sp1")
        print("✅ 已回滚到保存点 sp1")
        
        # 提交最终结果
        conn.commit()
        print("✅ 事务提交完成")
        
    except Exception as e:
        conn.rollback()
        print(f"❌ 事务失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 调用
transaction_with_savepoint()

7.2 调用存储过程

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql

db_config = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "你的密码",
    "database": "test_db",
    "charset": "utf8mb4"
}

# 调用存储过程
def call_procedure():
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()
    
    try:
        # 调用名为 get_user_count 的存储过程
        cursor.callproc("get_user_count")
        # 获取结果
        result = cursor.fetchone()
        print("✅ 存储过程执行结果:", result)
        conn.commit()
    except Exception as e:
        print(f"❌ 调用失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 调用
call_procedure()

7.3 连接池使用(高并发必备)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
import pymysql
from dbutils.pooled_db import PooledDB

# 连接池配置
pool = PooledDB(
    creator=pymysql,
    maxconnections=10,    # 最大连接数
    mincached=2,           # 初始化空闲连接
    maxcached=5,           # 最大空闲连接
    maxshared=3,           # 最大共享连接
    blocking=True,         # 无连接时阻塞
    host="127.0.0.1",
    port=3306,
    user="root",
    password="你的密码",
    database="test_db",
    charset="utf8mb4"
)

# 从连接池获取连接
def get_conn_from_pool():
    conn = pool.connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    print("✅ 从连接池获取连接成功")
    return conn, cursor

# 使用连接池查询
def query_with_pool():
    conn, cursor = get_conn_from_pool()
    try:
        cursor.execute("SELECT COUNT(*) AS count FROM user;")
        print("✅ 查询结果:", cursor.fetchone())
    finally:
        cursor.close()
        conn.close()  # 归还连接池,不真正关闭

# 调用
query_with_pool()

八、最佳实践分享

8.1 安全最佳实践

  1. 必用参数化查询,严禁字符串拼接 SQL,彻底杜绝 SQL 注入
  2. 密码加密存储,使用 MD5/SHA256 加密,不存明文
  3. 最小权限原则,业务账号仅授予必要权限,不使用 root 运行
  4. 异常捕获全覆盖,避免程序崩溃与信息泄露
  5. 关闭自动提交,手动控制事务,保证数据一致性

8.2 性能最佳实践

  1. 高并发必用连接池,禁止频繁创建 / 关闭连接
  2. 批量操作必用 executemany,减少网络 IO
  3. 查询只查需要字段 ,禁止 SELECT *
  4. 大结果集分页查询,避免内存溢出
  5. 索引优化,查询字段建立索引,提升速度

8.3 代码规范最佳实践

  1. 配置抽离为常量,不硬编码密码
  2. 封装通用数据库工具类,复用代码
  3. 统一异常处理,统一日志输出
  4. 资源强制释放,使用上下文管理器
  5. 注释完整,SQL 语句格式化清晰

九、常见问题解答

Q1:报错 Access denied for user 'root'@'localhost'

原因 :用户名 / 密码错误、MySQL 服务未启动、权限不足解决

  1. 核对账号密码
  2. 启动 MySQL 服务
  3. 授权远程访问:GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '密码';

Q2:报错 UnicodeEncodeError: 'latin-1' codec can't encode character

原因 :字符集设置错误,未使用 utf8mb4解决 :连接时强制指定 charset="utf8mb4"

Q3:插入数据不生效,无报错

原因 :未执行 conn.commit() 提交事务解决:增删改操作必须手动提交

Q4:远程连接超时

原因 :服务器防火墙未开放 3306 端口、MySQL 绑定本地 IP解决

  1. 防火墙放行 3306 端口
  2. 修改 MySQL 配置 bind-address = 0.0.0.0

Q5:查询结果为 None

原因 :无匹配数据、SQL 错误、游标未正确创建解决:核对 SQL 语句、检查参数、确认数据存在


十、总结与展望

10.1 核心要点回顾

  1. pymysql 是 Python 操作 MySQL 的首选纯 Python 库,跨平台、无依赖
  2. 核心流程:建立连接 → 创建游标 → 执行 SQL → 提交 / 回滚 → 关闭资源
  3. 安全第一:参数化查询 防止 SQL 注入,生产环境禁用字符串拼接
  4. 性能关键:连接池 + 批量操作 + 事务优化 支撑高并发场景
  5. 规范编码:异常处理、资源释放、代码封装是项目稳定的基础

10.2 未来发展趋势

  1. pymysql 持续兼容 MySQL 8.0+ 新特性,支持更多高级语法
  2. 与 AI 框架结合,实现数据库智能查询、自动化运维
  3. 异步版本 aiomysql 成为高并发 Web 服务主流
  4. 云原生场景下,pymysql 适配云数据库 RDS 自动连接

10.3 学习建议

  1. 先练基础:掌握连接、CRUD、异常处理,再学高级特性
  2. 结合实战:用 Flask/Django 搭建项目,真实场景使用 pymysql
  3. 深入原理:理解事务、连接池、MySQL 协议,提升排查能力
  4. 持续跟进:关注 pymysql 版本更新,学习新特性

十一、完整工具类封装(可直接用于项目)

python

运行

python 复制代码
# -*- coding: utf-8 -*-
"""
pymysql 通用工具类(生产环境可用)
"""
import pymysql
from pymysql import err
from typing import List, Dict, Any, Optional

class PyMySQLUtil:
    def __init__(self, host: str, port: int, user: str, password: str, database: str, charset: str = "utf8mb4"):
        """初始化数据库配置"""
        self.db_config = {
            "host": host,
            "port": port,
            "user": user,
            "password": password,
            "database": database,
            "charset": charset
        }
    
    def __get_conn(self) -> Optional[tuple[pymysql.Connection, pymysql.cursors.DictCursor]]:
        """获取连接和字典游标(私有方法)"""
        try:
            conn = pymysql.connect(**self.db_config)
            cursor = conn.cursor(pymysql.cursors.DictCursor)
            return conn, cursor
        except Exception as e:
            print(f"❌ 获取连接失败:{e}")
            return None
    
    def execute(self, sql: str, params: tuple = None) -> int:
        """执行增删改 SQL,返回影响行数"""
        conn, cursor = self.__get_conn()
        if not conn or not cursor:
            return -1
        
        try:
            cursor.execute(sql, params)
            conn.commit()
            return cursor.rowcount
        except Exception as e:
            conn.rollback()
            print(f"❌ 执行失败:{e}")
            return -1
        finally:
            cursor.close()
            conn.close()
    
    def executemany(self, sql: str, params: List[tuple]) -> int:
        """批量执行 SQL"""
        conn, cursor = self.__get_conn()
        if not conn or not cursor:
            return -1
        
        try:
            cursor.executemany(sql, params)
            conn.commit()
            return cursor.rowcount
        except Exception as e:
            conn.rollback()
            print(f"❌ 批量执行失败:{e}")
            return -1
        finally:
            cursor.close()
            conn.close()
    
    def fetch_one(self, sql: str, params: tuple = None) -> Optional[Dict[str, Any]]:
        """查询单条数据"""
        conn, cursor = self.__get_conn()
        if not conn or not cursor:
            return None
        
        try:
            cursor.execute(sql, params)
            return cursor.fetchone()
        except Exception as e:
            print(f"❌ 查询失败:{e}")
            return None
        finally:
            cursor.close()
            conn.close()
    
    def fetch_all(self, sql: str, params: tuple = None) -> List[Dict[str, Any]]:
        """查询多条数据"""
        conn, cursor = self.__get_conn()
        if not conn or not cursor:
            return []
        
        try:
            cursor.execute(sql, params)
            return cursor.fetchall()
        except Exception as e:
            print(f"❌ 查询失败:{e}")
            return []
        finally:
            cursor.close()
            conn.close()

# 使用示例
if __name__ == "__main__":
    # 初始化工具类
    db = PyMySQLUtil(
        host="127.0.0.1",
        port=3306,
        user="root",
        password="你的密码",
        database="test_db"
    )
    
    # 查询所有用户
    users = db.fetch_all("SELECT id, username FROM user;")
    print("所有用户:", users)
相关推荐
czlczl200209252 小时前
MySQL 性能优化:前缀索引(Prefix Index)深度解析
数据库·mysql·性能优化
y = xⁿ3 小时前
MySQL八股知识合集
android·mysql·adb
一只小白菜3 小时前
macOS MySQL 简易操作手册(基于 zsh + MySQL 8.0.24)
adb
计算机安禾3 小时前
【Linux从入门到精通】第33篇:数据库MySQL/MariaDB安装与基础调优
linux·数据库·mysql
tang&4 小时前
【MySQL】索引创建与B+树原理:MySQL性能优化的核心一课
b树·mysql·性能优化
sitellla4 小时前
MySQL 入门:最流行的开源关系型数据库介绍
数据库·mysql·其他·开源
2301_808414384 小时前
MySQL表的约束
数据库·mysql
小米渣的逆袭5 小时前
Android ADB 完全使用指南
android·adb
小碗羊肉5 小时前
【MySQL | 第五篇】事务
数据库·mysql