Python3 MySQL - mysql-connector 驱动详解
mysql-connector 是 MySQL 官方提供的 Python 驱动程序,用于在 Python3 中连接和操作 MySQL 或 MariaDB 数据库。它支持 Python DB API 2.0 规范,提供了丰富的功能,包括连接管理、SQL 执行、事务处理、异常处理等。本文将详细讲解其使用方法。
一、安装 mysql-connector
首先需要通过
pip 安装官方驱动,注意包名为 mysql-connector-python(避免与其他非官方包混淆):pip install mysql-connector-python
验证安装是否成功:
import mysql.connector
print(mysql.connector.__version__) # 输出版本号,如 8.0.33
二、连接数据库
使用
mysql.connector.connect() 方法创建数据库连接,需指定连接参数(主机、用户、密码、数据库名等)。基本连接示例:
import mysql.connector
# 连接参数
config = {
"host": "localhost", # 数据库主机地址
"user": "root", # 用户名
"password": "your_password", # 密码
"database": "test_db", # 要连接的数据库名(可选)
"port": 3306, # 端口(默认3306)
"charset": "utf8mb4" # 字符集(支持中文)
}
try:
# 建立连接
conn = mysql.connector.connect(**config)
if conn.is_connected():
print("数据库连接成功!")
except mysql.connector.Error as e:
print(f"连接失败:{e}")
finally:
# 关闭连接(重要!避免资源泄露)
if 'conn' in locals() and conn.is_connected():
conn.close()
print("连接已关闭")
关键连接参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
host |
数据库主机地址(IP 或域名) | localhost |
user |
登录用户名 | 无 |
password |
登录密码 | 无 |
database |
连接后默认使用的数据库 | 无 |
port |
数据库端口 | 3306 |
charset |
字符编码(推荐 utf8mb4 支持 emoji) |
utf8 |
autocommit |
是否自动提交事务(True/False) |
False |
三、执行 SQL 语句(CRUD 操作)
连接成功后,通过 游标(cursor) 执行 SQL 语句。游标是操作数据库的核心对象,用于发送 SQL 命令和获取结果。
1. 创建游标
# 从连接对象获取游标
cursor = conn.cursor()
默认游标返回的结果是元组(
tuple),若需通过列名访问结果(如字典形式),可指定游标类型: # 创建字典游标(结果为字典,key为列名)
cursor = conn.cursor(dictionary=True)
2. 执行查询(SELECT)
使用
cursor.execute() 执行查询语句,通过 cursor.fetchone()(获取一条)或 cursor.fetchall()(获取所有)获取结果。示例:查询
users 表中的数据 try:
# 执行查询SQL
sql = "SELECT id, name, age FROM users WHERE age > %s"
cursor.execute(sql, (18,)) # %s 是占位符,参数以元组传入(防SQL注入)
# 获取所有结果
results = cursor.fetchall()
for row in results:
# 若为普通游标,通过索引访问:row[0](id)、row[1](name)
# 若为字典游标,通过键访问:row['id']、row['name']
print(f"ID: {row['id']}, 姓名: {row['name']}, 年龄: {row['age']}")
except mysql.connector.Error as e:
print(f"查询失败:{e}")
3. 执行插入(INSERT)
插入操作需通过
cursor.execute() 执行 INSERT 语句,且需调用 conn.commit() 提交事务(默认 autocommit=False)。示例:插入一条数据到
users 表try:
# 插入SQL
sql = "INSERT INTO users (name, age, email) VALUES (%s, %s, %s)"
# 插入的参数(可批量传入多个元组)
data = ("张三", 25, "zhangsan@example.com")
# 执行插入
cursor.execute(sql, data)
# 提交事务(关键!否则数据不会写入数据库)
conn.commit()
print(f"插入成功,新增记录ID:{cursor.lastrowid}") # 获取自增ID
except mysql.connector.Error as e:
# 出错时回滚事务
conn.rollback()
print(f"插入失败:{e}")
4. 执行更新(UPDATE)
更新操作与插入类似,需提交事务。
示例:更新
users 表中的数据try:
sql = "UPDATE users SET age = %s WHERE name = %s"
data = (26, "张三") # 将"张三"的年龄改为26
cursor.execute(sql, data)
conn.commit()
print(f"更新成功,影响行数:{cursor.rowcount}") # 获取影响的行数
except mysql.connector.Error as e:
conn.rollback()
print(f"更新失败:{e}")
5. 执行删除(DELETE)
删除操作同样需要提交事务。
示例:删除
users 表中的数据try:
sql = "DELETE FROM users WHERE id = %s"
data = (1,) # 删除ID为1的记录
cursor.execute(sql, data)
conn.commit()
print(f"删除成功,影响行数:{cursor.rowcount}")
except mysql.connector.Error as e:
conn.rollback()
print(f"删除失败:{e}")
四、参数化查询(防 SQL 注入)
严禁使用字符串拼接构造 SQL(会导致 SQL 注入漏洞),必须使用
%s 作为占位符,参数通过 execute() 方法的第二个参数传入。错误示例(危险!):
# 错误:字符串拼接导致SQL注入风险
name = "张三' OR '1'='1" # 恶意输入
sql = f"SELECT * FROM users WHERE name = '{name}'" # 拼接后SQL会查询所有数据
正确示例(安全):
# 正确:使用占位符
name = "张三' OR '1'='1"
sql = "SELECT * FROM users WHERE name = %s"
cursor.execute(sql, (name,)) # 参数以元组传入,驱动会自动转义
五、事务处理
mysql-connector 默认关闭自动提交(autocommit=False),需手动调用 commit() 提交事务;若操作失败,调用 rollback() 回滚。事务的 ACID 特性确保多步操作要么全部成功,要么全部失败(如转账场景):
try:
# 步骤1:扣减A的余额
sql1 = "UPDATE accounts SET balance = balance - 100 WHERE id = 1"
cursor.execute(sql1)
# 步骤2:增加B的余额
sql2 = "UPDATE accounts SET balance = balance + 100 WHERE id = 2"
cursor.execute(sql2)
# 全部成功,提交事务
conn.commit()
print("转账成功")
except mysql.connector.Error as e:
# 任何一步失败,回滚所有操作
conn.rollback()
print(f"转账失败,已回滚:{e}")
若需开启自动提交(不推荐,除非特殊场景):
conn.autocommit = True # 开启自动提交(所有操作立即生效,无需commit)
六、异常处理
mysql-connector 定义了多种异常,常用的有:| 异常类 | 说明 |
|---|---|
InterfaceError |
数据库连接相关错误(如连接失败) |
DatabaseError |
数据库操作错误(如 SQL 语法错误) |
ProgrammingError |
SQL 语法错误、表不存在等程序错误 |
IntegrityError |
数据完整性错误(如外键约束冲突) |
OperationalError |
数据库运行时错误(如连接超时) |
捕获异常的通用写法:
from mysql.connector import Error, InterfaceError, ProgrammingError
try:
# 数据库操作
...
except InterfaceError as e:
print(f"连接错误:{e}")
except ProgrammingError as e:
print(f"SQL语法错误:{e}")
except Error as e: # 捕获所有mysql-connector异常
print(f"数据库错误:{e}")
except Exception as e: # 捕获其他异常
print(f"未知错误:{e}")
七、连接池(提高性能)
在高频访问场景(如 Web 应用),频繁创建和关闭连接会消耗资源。使用连接池可复用连接,提升性能。
mysql.connector 提供 MySQLConnectionPool 实现连接池:from mysql.connector import pooling
# 配置连接池
pool_config = {
"host": "localhost",
"user": "root",
"password": "your_password",
"database": "test_db",
"pool_name": "mypool", # 连接池名称
"pool_size": 5, # 连接池大小(默认5)
"pool_reset_session": True # 从池获取连接时重置会话状态
}
# 创建连接池
pool = pooling.MySQLConnectionPool(** pool_config)
# 从连接池获取连接
conn = pool.get_connection()
cursor = conn.cursor()
# 执行操作(与普通连接用法一致)
cursor.execute("SELECT 1")
print(cursor.fetchone())
# 归还连接到池(无需关闭,关闭会从池移除)
conn.close()
八、高级特性:批量操作
对于批量插入 / 更新,使用
cursor.executemany() 比多次调用 execute() 更高效(减少网络交互)。示例:批量插入多条数据
try:
sql = "INSERT INTO users (name, age) VALUES (%s, %s)"
# 批量数据(列表中的每个元组对应一条记录)
data = [("李四", 22), ("王五", 30), ("赵六", 27)]
# 批量执行
cursor.executemany(sql, data)
conn.commit()
print(f"批量插入成功,共插入 {cursor.rowcount} 条记录")
except mysql.connector.Error as e:
conn.rollback()
print(f"批量插入失败:{e}")
九、常见问题与解决
-
中文乱码:连接时指定
charset="utf8mb4",并确保数据库表的字符集为utf8mb4。 -
连接超时:添加
connection_timeout参数设置超时时间(单位秒),如connection_timeout=30。 -
版本兼容性:
mysql-connector-python 8.0+支持 MySQL 8.0 的 caching_sha2_password 认证插件,若连接旧版本 MySQL(5.7 及以下),可能需要修改用户认证方式为mysql_native_password。 -
游标关闭:使用完游标后建议关闭(
cursor.close()),释放资源。
总结
mysql-connector 作为 MySQL 官方驱动,功能完善且兼容性好,适合在 Python3 中进行数据库操作。核心要点包括:- 用
connect()建立连接,指定正确的参数; - 通过游标执行 SQL,使用
%s占位符防注入; - 写操作需
commit(),失败时rollback(); - 高频场景使用连接池提升性能;
- 捕获异常确保程序健壮性。
掌握这些内容后,可轻松实现 Python 与 MySQL 的交互开发。
浙公网安备 33010602011771号