Python 操作 MySQL 数据库从入门到精通

前言:Python+MySQL 黄金技术栈

Python 与 MySQL 的组合,是 Web 后端、数据分析、自动化运维领域的核心技术栈。Python 简洁高效,MySQL 开源稳定,二者结合可快速搭建各类业务系统。本文精简核心内容,聚焦实用技能,避开冗余理论,从零基础到企业级应用,一站式掌握操作要点。


第一章 环境搭建:快速构建开发环境

1.1 MySQL 安装与初始化

1.1.1 快速安装(主流系统)
系统 安装命令 初始化步骤
Windows 官网下载 MySQL 8.0 + 安装包,选择 "Developer Default" 1. 设置 root 密码;2. 默认端口 3306;3. 启动服务
Mac brew install mysql 1. brew services start mysql;2. mysql_secure_installation设密码
Linux (Ubuntu) sudo apt update && sudo apt install mysql-server -y 1. sudo systemctl start mysql;2. 执行初始化脚本设密码
1.1.2 创建测试库表
复制代码
-- 创建数据库(支持emoji)
CREATE DATABASE IF NOT EXISTS python_mysql_demo CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE python_mysql_demo;

-- 创建用户表(核心测试表)
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
    username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
    password VARCHAR(100) NOT NULL COMMENT '加密密码',
    nickname VARCHAR(50) COMMENT '昵称',
    age INT DEFAULT 0 COMMENT '年龄',
    gender ENUM('男','女','未知') DEFAULT '未知' COMMENT '性别',
    email VARCHAR(100) UNIQUE COMMENT '邮箱',
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';

-- 插入测试数据
INSERT INTO users (username, password, nickname, age, gender, email)
VALUES 
('zhangsan', MD5('123456'), '张三', 25, '男', 'zhangsan@demo.com'),
('lisi', MD5('123456'), '李四', 28, '女', 'lisi@demo.com');

1.2 Python 驱动安装与选择

主流驱动两种,按需选择:

驱动 特点 安装命令 适用场景
mysql-connector-python Oracle 官方,稳定兼容 pip install mysql-connector-python 企业级项目、追求稳定性
PyMySQL 纯 Python 实现,轻量便捷 pip install pymysql 小型项目、快速开发

第二章 基础入门:连接与核心流程

2.1 数据库连接(两种方式)

2.1.1 mysql-connector 连接(推荐)
复制代码
import mysql.connector
from mysql.connector import Error

def connect_mysql():
    """连接MySQL(官方驱动)"""
    config = {
        "host": "localhost", "user": "root", "password": "123456",
        "database": "python_mysql_demo", "charset": "utf8mb4",
        "auth_plugin": "mysql_native_password"  # 兼容MySQL8.0认证
    }
    try:
        conn = mysql.connector.connect(**config)
        if conn.is_connected():
            print("✅ 连接成功")
            return conn
    except Error as e:
        print(f"❌ 连接失败:{e}")
    return None

# 测试连接
conn = connect_mysql()
if conn:
    conn.close()  # 用完关闭
2.1.2 PyMySQL 连接(替代)
复制代码
import pymysql
from pymysql import OperationalError

def connect_pymysql():
    """连接MySQL(PyMySQL)"""
    config = {
        "host": "localhost", "user": "root", "password": "123456",
        "database": "python_mysql_demo", "charset": "utf8mb4",
        "cursorclass": pymysql.cursors.DictCursor  # 字典游标,可读性强
    }
    try:
        conn = pymysql.connect(**config)
        print("✅ PyMySQL连接成功")
        return conn
    except OperationalError as e:
        print(f"❌ 连接失败:{e}")
    return None

# 测试连接
conn = connect_pymysql()
if conn:
    conn.close()

2.2 游标与核心流程

核心六步:连接→创建游标→执行 SQL→处理结果→提交事务→关闭资源

复制代码
def core_demo():
    """完整操作流程演示"""
    conn = connect_mysql()
    if not conn:
        return
    
    # 1. 创建字典游标(推荐)
    cursor = conn.cursor(dictionary=True)
    try:
        # 2. 执行SQL(查询前2条用户数据)
        sql = "SELECT * FROM users LIMIT 2"
        cursor.execute(sql)
        
        # 3. 处理结果
        results = cursor.fetchall()
        for row in results:
            print(f"ID:{row['id']},昵称:{row['nickname']}")
        
        # 4. 提交事务(增删改必须,查询无需)
        # conn.commit()
    except Error as e:
        # 5. 异常回滚
        conn.rollback()
        print(f"❌ 操作失败:{e}")
    finally:
        # 6. 关闭资源(必做!防连接泄漏)
        cursor.close()
        conn.close()
        print("🔌 资源已释放")

# 运行演示
core_demo()

第三章 CRUD 实战:核心操作全解

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

3.1.1 单条插入(防注入)

核心原则 :必须用%s占位符,禁止字符串拼接

复制代码
def insert_single():
    """单条插入用户"""
    conn = connect_mysql()
    if not conn:
        return
    
    cursor = conn.cursor()
    try:
        sql = "INSERT INTO users (username, password, nickname, age) VALUES (%s, %s, %s, %s)"
        params = ("wangwu", MD5('123456'), "王五", 30)
        cursor.execute(sql, params)
        conn.commit()  # 必须提交
        print(f"✅ 插入成功,新增ID:{cursor.lastrowid}")
    except Error as e:
        conn.rollback()
        print(f"❌ 插入失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 测试
insert_single()
3.1.2 批量插入(高效)
复制代码
def insert_batch():
    """批量插入用户"""
    conn = connect_mysql()
    if not conn:
        return
    
    cursor = conn.cursor()
    try:
        sql = "INSERT INTO users (username, password, nickname, age) VALUES (%s, %s, %s, %s)"
        # 批量参数:列表嵌套元组
        params_list = [
            ("zhaoliu", MD5('123456'), "赵六", 22),
            ("sunqi", MD5('123456'), "孙七", 24)
        ]
        cursor.executemany(sql, params_list)
        conn.commit()
        print(f"✅ 批量插入成功,影响行数:{cursor.rowcount}")
    except Error as e:
        conn.rollback()
        print(f"❌ 批量插入失败:{e}")
    finally:
        cursor.close()
        conn.close()

# 测试
insert_batch()

3.2 查询数据(基础 / 分页 / 聚合)

3.2.1 基础查询
复制代码
def query_basic():
    """基础查询(条件/全表)"""
    conn = connect_mysql()
    cursor = conn.cursor(dictionary=True)
    
    # 1. 全表查询
    cursor.execute("SELECT username, nickname FROM users")
    all_users = cursor.fetchall()
    print("🔍 所有用户:", all_users)
    
    # 2. 条件查询(年龄>25)
    cursor.execute("SELECT * FROM users WHERE age > %s", (25,))
    filter_users = cursor.fetchall()
    print("🔍 年龄>25的用户:", filter_users)
    
    # 3. 模糊查询(昵称含"张")
    cursor.execute("SELECT * FROM users WHERE nickname LIKE %s", ("%张%",))
    like_users = cursor.fetchall()
    print("🔍 昵称含张的用户:", like_users)
    
    cursor.close()
    conn.close()

# 测试
query_basic()
3.2.2 分页查询(企业必备)
复制代码
def query_page(page=1, page_size=2):
    """分页查询"""
    conn = connect_mysql()
    cursor = conn.cursor(dictionary=True)
    
    offset = (page - 1) * page_size  # 计算偏移量
    sql = "SELECT * FROM users LIMIT %s OFFSET %s"
    cursor.execute(sql, (page_size, offset))
    results = cursor.fetchall()
    
    print(f"📄 第{page}页(每页{page_size}条):")
    for row in results:
        print(row)
    
    cursor.close()
    conn.close()

# 测试
query_page(page=1)
3.2.3 聚合查询(统计数据)
复制代码
def query_aggregate():
    """用户统计查询"""
    conn = connect_mysql()
    cursor = conn.cursor(dictionary=True)
    
    sql = """
    SELECT COUNT(*) AS total, AVG(age) AS avg_age, MAX(age) AS max_age
    FROM users
    """
    cursor.execute(sql)
    stats = cursor.fetchone()
    
    print("📊 统计信息:")
    print(f"总用户数:{stats['total']}")
    print(f"平均年龄:{round(stats['avg_age'], 1)}")
    print(f"最大年龄:{stats['max_age']}")
    
    cursor.close()
    conn.close()

# 测试
query_aggregate()

3.3 更新数据(单条 / 批量)

3.3.1 单条更新
复制代码
def update_single(user_id, new_nickname):
    """更新用户昵称"""
    conn = connect_mysql()
    cursor = conn.cursor()
    
    sql = "UPDATE users SET nickname = %s WHERE id = %s"
    cursor.execute(sql, (new_nickname, user_id))
    conn.commit()
    
    if cursor.rowcount > 0:
        print(f"✅ 更新成功,影响行数:{cursor.rowcount}")
    else:
        print("⚠️ 未找到该用户")
    
    cursor.close()
    conn.close()

# 测试(更新ID=1的用户昵称)
update_single(1, "张三_更新")
3.3.2 批量更新
复制代码
def update_batch(age, new_age):
    """批量更新年龄"""
    conn = connect_mysql()
    cursor = conn.cursor()
    
    sql = "UPDATE users SET age = %s WHERE age = %s"
    cursor.execute(sql, (new_age, age))
    conn.commit()
    
    print(f"✅ 批量更新成功,影响行数:{cursor.rowcount}")
    cursor.close()
    conn.close()

# 测试(将25岁用户改为26岁)
update_batch(25, 26)

3.4 删除数据(单条 / 条件)

3.4.1 单条删除
复制代码
def delete_single(user_id):
    """根据ID删除用户"""
    conn = connect_mysql()
    cursor = conn.cursor()
    
    sql = "DELETE FROM users WHERE id = %s"
    cursor.execute(sql, (user_id,))
    conn.commit()
    
    if cursor.rowcount > 0:
        print(f"✅ 删除成功")
    else:
        print("⚠️ 未找到该用户")
    
    cursor.close()
    conn.close()

# 测试(删除ID=3的用户)
delete_single(3)
3.4.2 条件删除(慎用!)
复制代码
def delete_condition(age):
    """删除年龄小于指定值的用户"""
    conn = connect_mysql()
    cursor = conn.cursor()
    
    sql = "DELETE FROM users WHERE age < %s"
    cursor.execute(sql, (age,))
    conn.commit()
    
    print(f"✅ 条件删除成功,影响行数:{cursor.rowcount}")
    cursor.close()
    conn.close()

# 测试(删除年龄<23的用户)
delete_condition(23)

第四章 事务管理:保证数据安全

4.1 事务核心概念

事务是不可分割的操作序列,要么全成功,要么全回滚,具备 ACID 特性:原子性、一致性、隔离性、持久性。

4.2 Python 事务实现(模拟转账)

复制代码
def transaction_transfer(from_user, to_user, amount):
    """模拟转账(事务安全)"""
    conn = connect_mysql()
    if not conn:
        return
    
    cursor = conn.cursor()
    try:
        conn.autocommit = False  # 关闭自动提交,开启事务
        
        # 1. 扣款
        sql1 = "UPDATE users SET balance = balance - %s WHERE username = %s"
        cursor.execute(sql1, (amount, from_user))
        
        # 2. 入账
        sql2 = "UPDATE users SET balance = balance + %s WHERE username = %s"
        cursor.execute(sql2, (amount, to_user))
        
        conn.commit()  # 提交事务
        print("✅ 转账成功")
    except Error as e:
        conn.rollback()  # 回滚事务
        print(f"❌ 转账失败,已回滚:{e}")
    finally:
        conn.autocommit = True  # 恢复自动提交
        cursor.close()
        conn.close()

# 测试(需先给users表添加balance字段:ALTER TABLE users ADD COLUMN balance DECIMAL(10,2) DEFAULT 0.00;)
# transaction_transfer("zhangsan", "lisi", 100)

4.3 事务隔离级别(快速配置)

MySQL 默认隔离级别为REPEATABLE READ,可快速切换:

复制代码
def set_isolation_level():
    """设置事务隔离级别"""
    conn = connect_mysql()
    cursor = conn.cursor()
    
    # 查看当前级别
    cursor.execute("SELECT @@transaction_isolation")
    print("当前级别:", cursor.fetchone()[0])
    
    # 切换为READ COMMITTED(平衡性能与一致性)
    cursor.execute("SET SESSION transaction_isolation = 'READ-COMMITTED'")
    print("✅ 已切换为READ COMMITTED")
    
    cursor.close()
    conn.close()

# 测试
set_isolation_level()

第五章 高级特性:进阶开发要点

5.1 连接池(企业必备)

避免频繁创建 / 销毁连接,提升并发性能

复制代码
from mysql.connector import pooling

# 全局连接池
pool = None

def init_pool():
    """初始化连接池"""
    global pool
    config = {
        "host": "localhost", "user": "root", "password": "123456",
        "database": "python_mysql_demo", "charset": "utf8mb4",
        "pool_name": "python_pool", "pool_size": 5  # 池大小5
    }
    pool = pooling.MySQLConnectionPool(**config)
    print("✅ 连接池初始化完成")

def get_conn():
    """从池获取连接"""
    if not pool:
        init_pool()
    return pool.get_connection()

# 使用连接池查询
def query_with_pool():
    conn = get_conn()
    cursor = conn.cursor(dictionary=True)
    
    cursor.execute("SELECT username FROM users LIMIT 3")
    print(cursor.fetchall())
    
    cursor.close()
    conn.close()  # 归还连接到池,非关闭

# 测试
query_with_pool()

总结

本文从环境搭建、基础 CRUD、事务管理、高级特性、性能优化到实战项目,全面覆盖了 Python 操作 MySQL 的全流程知识体系。核心要点总结:

  1. 驱动选择:优先 mysql-connector-python(官方稳定),备用 PyMySQL(轻量便捷)
  2. 核心流程:连接→游标→执行→处理→提交→关闭,资源必须释放
  3. 安全第一:参数化查询防注入,密码加密存储,事务保证一致性
  4. 效率提升:批量操作、连接池、索引优化、ORM 框架
  5. 实战落地:封装工具类,异常处理 + 日志记录,适配企业开发
相关推荐
zxrhhm2 小时前
SQLServer限制特定数据库的CPU使用率,确保关键业务系统有足够的资源
数据库·sqlserver
The_Ticker2 小时前
印度股票实时行情API(低成本方案)
python·websocket·算法·金融·区块链
ZC跨境爬虫2 小时前
Scrapy工作空间搭建与目录结构解析:从初始化到基础配置全流程
前端·爬虫·python·scrapy·自动化
EAIReport2 小时前
国外网站数据批量采集技术实现路径
开发语言·python
Ulyanov2 小时前
基于ttk的现代化Python音视频播放器:UI设计与可视化技术深度解析
python·ui·音视频
刘~浪地球2 小时前
Redis 从入门到精通(十三):哨兵与集群
数据库·redis·缓存
Freak嵌入式2 小时前
MicroPython LVGL基础知识和概念:时序与动态效果
开发语言·python·github·php·gui·lvgl·micropython
Java开发追求者2 小时前
windows卸载mysql教程
mysql·mysql卸载
dyyshb3 小时前
PostgreSQL 终极兜底方案
数据库·postgresql