前言: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 的全流程知识体系。核心要点总结:
- 驱动选择:优先 mysql-connector-python(官方稳定),备用 PyMySQL(轻量便捷)
- 核心流程:连接→游标→执行→处理→提交→关闭,资源必须释放
- 安全第一:参数化查询防注入,密码加密存储,事务保证一致性
- 效率提升:批量操作、连接池、索引优化、ORM 框架
- 实战落地:封装工具类,异常处理 + 日志记录,适配企业开发