Python使用PyMySQL操作MySQL完整指南

Python使用PyMySQL操作MySQL完整指南

1. 安装依赖

bash 复制代码
pip install pymysql

2. 基础配置和数据库操作

2.1 基础配置类

python 复制代码
import pymysql
from typing import List, Dict, Optional
from datetime import datetime

class MySQLDB:
    def __init__(self):
        self.conn = None
        self.cursor = None

    def connect(self):
        """连接数据库"""
        try:
            self.conn = pymysql.connect(
                host='localhost',
                port=3306,
                user='root',
                password='123456',
                charset='utf8mb4',
                cursorclass=pymysql.cursors.DictCursor  # 返回字典格式
            )
            self.cursor = self.conn.cursor()
        except Exception as e:
            print(f"连接数据库失败:{e}")
            raise e

    def close(self):
        """关闭数据库连接"""
        if self.cursor:
            self.cursor.close()
        if self.conn:
            self.conn.close()

2.2 数据库和表操作

python 复制代码
    def create_database(self):
        """创建数据库"""
        try:
            sql = "CREATE DATABASE IF NOT EXISTS test DEFAULT CHARACTER SET utf8mb4"
            self.cursor.execute(sql)
            self.conn.select_db('test')  # 选择数据库
        except Exception as e:
            print(f"创建数据库失败:{e}")
            raise e

    def drop_database(self):
        """删除数据库"""
        try:
            sql = "DROP DATABASE IF EXISTS test"
            self.cursor.execute(sql)
        except Exception as e:
            print(f"删除数据库失败:{e}")
            raise e

    def create_table(self):
        """创建用户表"""
        try:
            sql = """
            CREATE TABLE IF NOT EXISTS users (
                id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '自增主键',
                username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
                password VARCHAR(100) NOT NULL COMMENT '密码',
                age INT COMMENT '年龄',
                create_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
                INDEX idx_username (username)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
            """
            self.cursor.execute(sql)
            self.conn.commit()
        except Exception as e:
            self.conn.rollback()
            print(f"创建表失败:{e}")
            raise e

3. CRUD操作

3.1 插入操作

python 复制代码
    def insert_user(self, username: str, password: str, age: int) -> int:
        """插入单个用户"""
        try:
            sql = "INSERT INTO users(username, password, age) VALUES (%s, %s, %s)"
            self.cursor.execute(sql, (username, password, age))
            self.conn.commit()
            return self.cursor.lastrowid  # 返回自增ID
        except Exception as e:
            self.conn.rollback()
            print(f"插入用户失败:{e}")
            raise e

    def batch_insert_users(self, users: List[Dict]):
        """批量插入用户"""
        try:
            sql = "INSERT INTO users(username, password, age) VALUES (%s, %s, %s)"
            values = [(user['username'], user['password'], user['age']) for user in users]
            self.cursor.executemany(sql, values)
            self.conn.commit()
        except Exception as e:
            self.conn.rollback()
            print(f"批量插入用户失败:{e}")
            raise e

3.2 查询操作

python 复制代码
    def get_user_by_id(self, user_id: int) -> Optional[Dict]:
        """根据ID查询用户"""
        try:
            sql = "SELECT * FROM users WHERE id = %s"
            self.cursor.execute(sql, (user_id,))
            return self.cursor.fetchone()
        except Exception as e:
            print(f"查询用户失败:{e}")
            raise e

    def get_users_by_age(self, min_age: int) -> List[Dict]:
        """查询大于指定年龄的用户"""
        try:
            sql = "SELECT * FROM users WHERE age > %s"
            self.cursor.execute(sql, (min_age,))
            return self.cursor.fetchall()
        except Exception as e:
            print(f"查询用户失败:{e}")
            raise e

    def get_users_with_pagination(self, page: int, page_size: int) -> List[Dict]:
        """分页查询用户"""
        try:
            offset = (page - 1) * page_size
            sql = "SELECT * FROM users LIMIT %s OFFSET %s"
            self.cursor.execute(sql, (page_size, offset))
            return self.cursor.fetchall()
        except Exception as e:
            print(f"分页查询失败:{e}")
            raise e

3.3 更新操作

python 复制代码
    def update_user(self, user_id: int, password: str = None, age: int = None) -> bool:
        """更新用户信息"""
        try:
            updates = []
            values = []
            if password is not None:
                updates.append("password = %s")
                values.append(password)
            if age is not None:
                updates.append("age = %s")
                values.append(age)
            
            if not updates:
                return False

            values.append(user_id)
            sql = f"UPDATE users SET {', '.join(updates)} WHERE id = %s"
            
            result = self.cursor.execute(sql, tuple(values))
            self.conn.commit()
            return result > 0
        except Exception as e:
            self.conn.rollback()
            print(f"更新用户失败:{e}")
            raise e

3.4 删除操作

python 复制代码
    def delete_user(self, user_id: int) -> bool:
        """删除用户"""
        try:
            sql = "DELETE FROM users WHERE id = %s"
            result = self.cursor.execute(sql, (user_id,))
            self.conn.commit()
            return result > 0
        except Exception as e:
            self.conn.rollback()
            print(f"删除用户失败:{e}")
            raise e

4. 使用示例

python 复制代码
def main():
    # 创建数据库实例
    db = MySQLDB()
    
    try:
        # 连接数据库
        db.connect()
        
        # 创建数据库和表
        db.create_database()
        db.create_table()
        
        # 插入单个用户
        user_id = db.insert_user("张三", "123456", 25)
        print(f"插入用户ID: {user_id}")
        
        # 批量插入用户
        users = [
            {"username": "李四", "password": "123456", "age": 26},
            {"username": "王五", "password": "123456", "age": 27}
        ]
        db.batch_insert_users(users)
        
        # 查询用户
        user = db.get_user_by_id(user_id)
        print(f"查询到的用户: {user}")
        
        # 更新用户
        db.update_user(user_id, age=30)
        
        # 分页查询
        users = db.get_users_with_pagination(1, 10)
        print(f"分页查询结果: {users}")
        
        # 删除用户
        db.delete_user(user_id)
        
    except Exception as e:
        print(f"操作失败:{e}")
    finally:
        db.close()

if __name__ == "__main__":
    main()

5. 事务处理示例

python 复制代码
def transfer_money(self, from_id: int, to_id: int, amount: float):
    """转账操作示例"""
    try:
        # 开始事务
        self.conn.begin()
        
        # 扣除转出账户金额
        sql1 = "UPDATE accounts SET balance = balance - %s WHERE id = %s AND balance >= %s"
        result1 = self.cursor.execute(sql1, (amount, from_id, amount))
        if result1 == 0:
            raise Exception("余额不足或账户不存在")
            
        # 增加转入账户金额
        sql2 = "UPDATE accounts SET balance = balance + %s WHERE id = %s"
        result2 = self.cursor.execute(sql2, (amount, to_id))
        if result2 == 0:
            raise Exception("转入账户不存在")
            
        # 提交事务
        self.conn.commit()
        return True
        
    except Exception as e:
        # 回滚事务
        self.conn.rollback()
        print(f"转账失败:{e}")
        raise e

6. 注意事项

  1. 连接管理

    • 及时关闭数据库连接
    • 使用连接池管理连接(可以使用 DBUtils 等库)
    • 处理连接超时情况
  2. 安全性

    • 使用参数化查询防止 SQL 注入
    • 妥善保管数据库凭证
    • 最小权限原则
  3. 性能优化

    • 合理使用索引
    • 批量操作代替循环单条操作
    • 避免查询无用字段
  4. 错误处理

    • 完善的异常处理机制
    • 事务回滚
    • 日志记录
相关推荐
宸码3 分钟前
【机器学习】【集成学习——决策树、随机森林】从零起步:掌握决策树、随机森林与GBDT的机器学习之旅
人工智能·python·算法·决策树·随机森林·机器学习·集成学习
Mobius80861 小时前
探索 Seaborn Palette 的奥秘:为数据可视化增色添彩
图像处理·python·信息可视化·数据分析·pandas·matplotlib·数据可视化
星霜旅人2 小时前
【Python】pandas库---数据分析
python
小陈phd2 小时前
深度学习之目标检测——RCNN
python·深度学习·算法·计算机视觉
从以前3 小时前
Python 爱心代码实现动态爱心图案展示
python
旷野..3 小时前
Python构造方法:对象的“开机启动程序”
开发语言·python
觅远3 小时前
python实现Excel转图片
开发语言·python·excel
Code_流苏3 小时前
VSCode 搭建Python编程环境 2024新版图文安装教程(Python环境搭建+VSCode安装+运行测试+背景图设置)
ide·vscode·python·python环境搭建·测试运行
口_天_光健3 小时前
两款轻量级数据库SQLite 和 TinyDB,简单!实用!
数据库·python·sqlite·非关系型数据库