一、章节学习目标
本章聚焦 Python 与 MySQL 数据库的交互核心技术,通过系统化讲解,帮助开发者掌握从环境搭建到复杂数据操作的全流程。学习完成后,你将达成以下目标:
- 熟练安装并配置 Python 操作 MySQL 的核心驱动库,理解不同驱动的适用场景。
- 掌握 Python 与 MySQL 数据库的连接、断开及异常处理机制,保障数据库操作的稳定性。
- 精通数据表的创建、删除等基础管理操作,能够通过 Python 代码完成数据库结构的动态维护。
- 熟练运用
INSERT、UPDATE、DELETE、SELECT四大核心 SQL 语句,实现数据的增删改查。 - 掌握事务管理、连接池配置等高级特性,提升数据库操作的安全性与性能。
- 能够处理数据库操作中的常见异常,编写健壮、可维护的 Python 数据库操作代码。
二、前置准备:安装 Python MySQL 连接库
Python 与 MySQL 数据库的交互依赖于第三方驱动库,目前主流的有mysql-connector-python(MySQL 官方驱动)和PyMySQL(纯 Python 轻量级驱动),二者核心特性与安装方式如下表所示:
表格
| 驱动库名称 | 核心特性 | 安装命令 | 适用场景 |
|---|---|---|---|
| mysql-connector-python | 1. MySQL 官方开发维护,文档完善、持续更新2. 纯 Python 实现,无需依赖外部 C 库3. 支持 SSL 加密、预处理语句、事务控制4. 符合 DB-API 2.0 规范,兼容性强 | pip install mysql-connector-python |
企业级应用、需要与 MySQL 官方特性深度集成、对兼容性要求高的项目 |
| PyMySQL | 1. 纯 Python 编写,轻量级、安装便捷2. 社区活跃,性能表现优异3. 语法简洁,上手成本低 | pip install pymysql |
中小型项目、脚本自动化、快速开发原型、追求轻量级依赖的场景 |
2.1 安装验证
安装完成后,可通过以下 Python 代码验证驱动是否安装成功:
python
运行
# 验证mysql-connector-python
try:
import mysql.connector
print(f"mysql-connector-python版本:{mysql.connector.__version__}")
print("✅ 安装成功!")
except ImportError:
print("❌ 未安装mysql-connector-python,请执行pip安装命令")
# 验证PyMySQL
try:
import pymysql
print(f"PyMySQL版本:{pymysql.__version__}")
print("✅ 安装成功!")
except ImportError:
print("❌ 未安装PyMySQL,请执行pip安装命令")
三、Python 连接 MySQL 数据库
连接 MySQL 是数据库操作的基础,核心包括连接配置、建立连接、游标创建、异常处理和连接关闭五个步骤,以下以mysql-connector-python为例详细讲解。
3.1 连接参数详解
建立连接时需配置核心参数,各参数含义及取值建议如下表:
表格
| 参数名 | 含义 | 取值建议 | 必选 |
|---|---|---|---|
| host | 数据库服务器地址 | 本地填localhost或127.0.0.1;远程填服务器 IP / 域名 |
是 |
| port | 数据库端口号 | MySQL 默认端口为3306,若修改过需对应填写 |
是 |
| database | 目标数据库名 | 需提前在 MySQL 中创建的数据库名称 | 是 |
| user | 数据库用户名 | 生产环境建议使用专用账号,避免使用 root | 是 |
| password | 数据库密码 | 对应用户名的登录密码,生产环境禁止硬编码 | 是 |
| charset | 字符集 | 推荐utf8mb4(支持 emoji,兼容所有 Unicode 字符) |
否 |
| autocommit | 自动提交模式 | False(手动控制事务,推荐);True(自动提交,适合简单查询) |
否 |
| ssl_ca/ssl_cert/ssl_key | SSL 加密配置 | 远程连接需加密时,填写 SSL 证书路径 | 否 |
3.2 基础连接代码(mysql-connector-python)
python
运行
import mysql.connector
from mysql.connector import Error
# 数据库连接配置
db_config = {
"host": "localhost",
"port": 3306,
"database": "test_db", # 需提前在MySQL中创建
"user": "root",
"password": "your_password",
"charset": "utf8mb4",
"autocommit": False
}
# 全局变量存储连接和游标
conn = None
cursor = None
try:
# 1. 建立数据库连接
conn = mysql.connector.connect(**db_config)
if conn.is_connected():
# 2. 获取MySQL服务器版本信息
db_version = conn.get_server_info()
print(f"✅ 成功连接MySQL服务器,版本:{db_version}")
# 3. 创建游标对象(用于执行SQL语句)
cursor = conn.cursor()
# 4. 执行基础查询,查看当前数据库
cursor.execute("SELECT DATABASE();")
current_db = cursor.fetchone()[0]
print(f"📌 当前操作数据库:{current_db}")
except Error as e:
# 异常处理:打印错误信息
print(f"❌ 数据库操作异常:{e}")
# 发生异常时回滚事务(若连接已建立)
if conn:
conn.rollback()
finally:
# 5. 关闭游标和连接,释放资源
if cursor:
cursor.close()
if conn and conn.is_connected():
conn.close()
print("🔌 数据库连接已关闭")
3.3 连接优化与异常处理
3.3.1 上下文管理器(with 语句)
使用with语句可自动管理资源,无需手动关闭连接和游标,代码更简洁、更安全:
python
运行
import mysql.connector
from mysql.connector import Error
db_config = {
"host": "localhost",
"database": "test_db",
"user": "root",
"password": "your_password",
"charset": "utf8mb4"
}
try:
# with语句自动管理连接和游标
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 执行SQL语句
cursor.execute("SELECT VERSION();")
version = cursor.fetchone()
print(f"MySQL版本:{version[0]}")
# 提交事务(非查询操作需手动提交)
conn.commit()
except Error as e:
print(f"❌ 异常:{e}")
3.3.2 常见连接异常排查
表格
| 异常码 | 异常原因 | 解决方法 |
|---|---|---|
| 1045 | 用户名 / 密码错误 | 检查user和password配置,确认账号密码正确 |
| 2003 | 无法连接到主机 | 检查host是否正确,确认 MySQL 服务已启动、端口未被占用 |
| 1049 | 数据库不存在 | 提前在 MySQL 中创建目标数据库,或检查database配置 |
| 2059 | 认证方式不兼容 | MySQL8.0 + 使用caching_sha2_password认证,需修改用户认证方式或安装对应驱动版本 |
四、数据表基础操作
通过 Python 代码可实现数据表的创建、删除、查看等管理操作,以下为核心操作详解。
4.1 创建数据表
创建数据表时需定义表名、字段名、数据类型、约束条件(主键、非空、唯一等),示例代码如下:
python
运行
import mysql.connector
from mysql.connector import Error
# 连接配置
db_config = {
"host": "localhost",
"database": "test_db",
"user": "root",
"password": "your_password",
"charset": "utf8mb4"
}
# 建表SQL语句(员工表)
create_table_sql = """
CREATE TABLE IF NOT EXISTS employees (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID,自增主键',
name VARCHAR(50) NOT NULL COMMENT '员工姓名',
age TINYINT UNSIGNED COMMENT '员工年龄',
department VARCHAR(100) NOT NULL COMMENT '所属部门',
salary DECIMAL(10, 2) NOT NULL COMMENT '薪资',
hire_date DATE NOT NULL COMMENT '入职日期',
email VARCHAR(100) UNIQUE COMMENT '邮箱,唯一',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工信息表';
"""
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 执行建表语句
cursor.execute(create_table_sql)
print("✅ 数据表employees创建成功(若已存在则跳过)")
# 查看表结构
cursor.execute("DESC employees;")
table_structure = cursor.fetchall()
print("\n📋 表结构信息:")
for field in table_structure:
print(f"字段名:{field[0]}, 类型:{field[1]}, 约束:{field[2]}")
except Error as e:
print(f"❌ 建表异常:{e}")
4.2 数据表删除
删除数据表需谨慎操作,数据删除后不可恢复,示例代码:
python
运行
# 删表SQL语句
drop_table_sql = "DROP TABLE IF EXISTS employees;"
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
cursor.execute(drop_table_sql)
print("✅ 数据表employees已删除(若存在)")
except Error as e:
print(f"❌ 删表异常:{e}")
4.3 数据表查看
查看数据库中所有数据表,代码如下:
python
运行
# 查看表SQL语句
show_tables_sql = "SHOW TABLES;"
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
cursor.execute(show_tables_sql)
tables = cursor.fetchall()
print(f"\n📌 数据库{db_config['database']}中的数据表:")
for table in tables:
print(f"- {table[0]}")
except Error as e:
print(f"❌ 查看表异常:{e}")
五、核心数据操作(CRUD)
CRUD 是数据库操作的核心,包括数据插入(Create)、查询(Read)、更新(Update)、删除(Delete),以下结合employees表详细讲解各操作。
5.1 数据插入(INSERT)
数据插入分为单条插入和批量插入,推荐使用参数化查询(%s占位符),避免 SQL 注入攻击。
5.1.1 单条插入
python
运行
import mysql.connector
from mysql.connector import Error
db_config = {
"host": "localhost",
"database": "test_db",
"user": "root",
"password": "your_password",
"charset": "utf8mb4"
}
# 单条插入SQL
insert_single_sql = """
INSERT INTO employees (name, age, department, salary, hire_date, email)
VALUES (%s, %s, %s, %s, %s, %s);
"""
# 插入数据
employee_data = ("张三", 28, "技术部", 15000.00, "2023-01-15", "zhangsan@example.com")
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 执行插入
cursor.execute(insert_single_sql, employee_data)
# 提交事务(非查询操作必须提交)
conn.commit()
# 获取自增主键ID
new_id = cursor.lastrowid
print(f"✅ 单条插入成功,新增员工ID:{new_id}")
print(f"📌 受影响行数:{cursor.rowcount}")
except Error as e:
# 异常时回滚
conn.rollback()
print(f"❌ 单条插入异常:{e}")
5.1.2 批量插入
批量插入使用executemany()方法,效率远高于多次单条插入,适合大量数据导入:
python
运行
# 批量插入SQL(复用单条插入语句)
insert_batch_sql = """
INSERT INTO employees (name, age, department, salary, hire_date, email)
VALUES (%s, %s, %s, %s, %s, %s);
"""
# 批量数据
batch_employee_data = [
("李四", 30, "销售部", 12000.00, "2023-02-20", "lisi@example.com"),
("王五", 25, "人事部", 9000.00, "2023-03-10", "wangwu@example.com"),
("赵六", 35, "财务部", 18000.00, "2023-01-05", "zhaoliu@example.com")
]
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 批量插入
cursor.executemany(insert_batch_sql, batch_employee_data)
conn.commit()
print(f"✅ 批量插入成功,新增{cursor.rowcount}条数据")
except Error as e:
conn.rollback()
print(f"❌ 批量插入异常:{e}")
5.2 数据查询(SELECT)
数据查询是最常用的操作,支持单条查询、多条查询、条件查询、模糊查询等,可通过fetchone()、fetchall()、fetchmany()获取结果。
5.2.1 基础查询
python
运行
# 查询所有员工数据
query_all_sql = "SELECT * FROM employees;"
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 执行查询
cursor.execute(query_all_sql)
# 获取所有结果
all_employees = cursor.fetchall()
print(f"\n📋 共查询到{len(all_employees)}条员工数据:")
# 遍历结果
for emp in all_employees:
print(f"ID:{emp[0]}, 姓名:{emp[1]}, 部门:{emp[3]}, 薪资:{emp[4]}")
except Error as e:
print(f"❌ 查询异常:{e}")
5.2.2 条件查询
python
运行
# 按部门查询员工(条件查询)
query_dept_sql = "SELECT name, salary, hire_date FROM employees WHERE department = %s;"
dept_name = "技术部"
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
cursor.execute(query_dept_sql, (dept_name,))
# 获取单条结果(若存在)
tech_emp = cursor.fetchone()
if tech_emp:
print(f"\n📌 技术部员工:姓名={tech_emp[0]}, 薪资={tech_emp[1]}, 入职日期={tech_emp[2]}")
else:
print("📌 技术部无员工数据")
except Error as e:
print(f"❌ 条件查询异常:{e}")
5.2.3 分页查询
python
运行
# 分页查询(每页2条,第1页)
page_query_sql = "SELECT * FROM employees LIMIT %s OFFSET %s;"
page_size = 2
page_num = 1
offset = (page_num - 1) * page_size
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
cursor.execute(page_query_sql, (page_size, offset))
page_employees = cursor.fetchall()
print(f"\n📋 第{page_num}页数据(每页{page_size}条):")
for emp in page_employees:
print(f"ID:{emp[0]}, 姓名:{emp[1]}")
except Error as e:
print(f"❌ 分页查询异常:{e}")
5.2.4 模糊查询
python
运行
# 模糊查询(姓名包含"张"的员工)
fuzzy_query_sql = "SELECT name, department FROM employees WHERE name LIKE %s;"
search_key = "%张%"
try:
with mysql.connector.connect(**db_config) as conn:
with conn.cursor() as cursor:
cursor.execute(fuzzy_query_sql, (search_key,))
fuzzy_emps = cursor.fetchall()
print(f"\n📋 姓名包含"张"的员工:")
for emp in fuzzy_emps:
print(f"姓名:{emp[0]},