MySQLdb 的现状
在开始之前,必须了解一个关键点:MySQLdb 库已经很久没有更新了,它主要使用 C 语言编写,依赖于 MySQL 的 C 客户端库,这意味着:

- Python 3 不兼容:
MySQLdb原生不支持 Python 3,如果你尝试在 Python 3 环境下pip install MySQLdb,会报错。 - 依赖复杂:安装它需要先安装 MySQL 的 C 开发库(在 Ubuntu/Debian 上是
libmysqlclient-dev,在 macOS 上是mysql-connector-c),这增加了部署的复杂性。
对于新项目,强烈推荐使用更现代、更易用的替代库,
mysql-connector-python:MySQL 官方提供的纯 Python 驱动,安装简单,支持 Python 3。PyMySQL:一个纯 Python 实现的 MySQL 客户端库,安装简单,支持 Python 3。
由于一些遗留系统或特定环境仍在使用 MySQLdb,了解它的用法仍然是有价值的,下面我们将为你提供一份完整的 MySQLdb 文档和使用指南。
MySQLdb 文档与使用指南
安装
如前所述,直接 pip install MySQLdb 在 Python 3 下会失败,你需要先安装 C 库,然后再安装 Python 包。
对于 Linux (Ubuntu/Debian):

# 1. 安装 MySQL C 开发库 sudo apt-get update sudo apt-get install libmysqlclient-dev python3-dev # 2. 使用 pip 安装 MySQLdb pip install MySQLdb
对于 macOS (使用 Homebrew):
# 1. 安装 MySQL C 库 brew install mysql-client # 2. 设置环境变量,让 pip 能找到它 export LDFLAGS="-L$(brew --prefix mysql-client)/lib" export CPPFLAGS="-I$(brew --prefix mysql-client)/include" # 3. 使用 pip 安装 MySQLdb pip install MySQLdb
对于 Windows:
在 Windows 上安装 MySQLdb 非常困难,通常不推荐,最好直接使用 mysql-connector-python 或 PyMySQL。
基本连接
使用 MySQLdb.connect() 函数建立与数据库的连接。
import MySQLdb
# --- 连接参数 ---
# host: 数据库服务器地址
# user: 数据库用户名
# passwd: 数据库密码
# db: 要连接的数据库名
# port: 数据库端口号,默认是 3306
# charset: 字符集,强烈建议使用 'utf8mb4'
db = MySQLdb.connect(
host="localhost",
user="your_username",
passwd="your_password",
db="your_database",
charset='utf8mb4'
)
# 获取游标对象
# 游标用于执行 SQL 语句
cursor = db.cursor()
执行 SQL 语句
游标对象 (cursor) 是执行所有数据库操作的核心。
1 创建表
# 使用 try-except-finally 结构确保资源被正确释放
try:
# 创建一个名为 users 的表
create_table_sql = """
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""
cursor.execute(create_table_sql)
print("表创建成功或已存在。")
# 提交事务
db.commit()
except MySQLdb.Error as e:
# 发生错误时回滚事务
db.rollback()
print(f"创建表时出错: {e}")
finally:
# 关闭游标
cursor.close()
2 插入数据 (单条)
try:
insert_sql = "INSERT INTO users (name, email, age) VALUES (%s, %s, %s)"
# 使用 %s 作为占位符,防止 SQL 注入
# 数据以元组形式传递
user_data = ("张三", "zhangsan@example.com", 30)
cursor.execute(insert_sql, user_data)
# 提交事务,使更改生效
db.commit()
print(f"成功插入数据,ID: {cursor.lastrowid}") # 获取最后插入行的ID
except MySQLdb.Error as e:
db.rollback()
print(f"插入数据时出错: {e}")
finally:
cursor.close()
3 插入数据 (批量)
try:
insert_sql = "INSERT INTO users (name, email, age) VALUES (%s, %s, %s)"
# 数据以列表的元组形式传递
users_data = [
("李四", "lisi@example.com", 25),
("王五", "wangwu@example.com", 28),
("赵六", "zhaoliu@example.com", 35)
]
# executemany 用于批量执行
cursor.executemany(insert_sql, users_data)
db.commit()
print(f"成功插入 {cursor.rowcount} 条数据。")
except MySQLdb.Error as e:
db.rollback()
print(f"批量插入数据时出错: {e}")
finally:
cursor.close()
4 查询数据
try:
query_sql = "SELECT id, name, email, age FROM users WHERE age > %s"
age_param = 28
cursor.execute(query_sql, (age_param,)) # 注意元组后的逗号
# 获取所有查询结果
results = cursor.fetchall()
print("查询结果:")
for row in results:
# row 是一个元组,(1, '张三', 'zhangsan@example.com', 30)
print(f"ID: {row[0]}, 姓名: {row[1]}, 邮箱: {row[2]}, 年龄: {row[3]}")
except MySQLdb.Error as e:
print(f"查询数据时出错: {e}")
finally:
cursor.close()
获取结果的几种方法:
cursor.fetchall(): 获取所有剩余的行。cursor.fetchone(): 获取下一行,如果结果为空则返回None。cursor.fetchmany(size): 获取指定数量的行。
5 更新数据
try:
update_sql = "UPDATE users SET age = %s WHERE name = %s"
new_age = 31
user_name = "张三"
cursor.execute(update_sql, (new_age, user_name))
db.commit()
print(f"成功更新 {cursor.rowcount} 条数据。")
except MySQLdb.Error as e:
db.rollback()
print(f"更新数据时出错: {e}")
finally:
cursor.close()
6 删除数据
try:
delete_sql = "DELETE FROM users WHERE name = %s"
user_name = "王五"
cursor.execute(delete_sql, (user_name,))
db.commit()
print(f"成功删除 {cursor.rowcount} 条数据。")
except MySQLdb.Error as e:
db.rollback()
print(f"删除数据时出错: {e}")
finally:
cursor.close()
完整示例
下面是一个将上述操作串联起来的完整脚本示例。
import MySQLdb
import sys
def main():
# --- 连接参数 ---
db_config = {
"host": "localhost",
"user": "your_username",
"passwd": "your_password",
"db": "your_database",
"charset": 'utf8mb4'
}
connection = None
try:
# 1. 建立连接
connection = MySQLdb.connect(**db_config)
cursor = connection.cursor()
# 2. 创建表
print("正在创建表...")
cursor.execute("DROP TABLE IF EXISTS users") # 先删除旧表,方便测试
create_table_sql = """
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
age INT
)
"""
cursor.execute(create_table_sql)
connection.commit()
print("表创建成功。")
# 3. 插入数据
print("\n正在插入数据...")
insert_sql = "INSERT INTO users (name, email, age) VALUES (%s, %s, %s)"
users_to_insert = [("Alice", "alice@example.com", 28), ("Bob", "bob@example.com", 32)]
cursor.executemany(insert_sql, users_to_insert)
connection.commit()
print(f"成功插入 {cursor.rowcount} 条数据。")
# 4. 查询数据
print("\n正在查询所有用户...")
cursor.execute("SELECT id, name, email, age FROM users")
all_users = cursor.fetchall()
for user in all_users:
print(f"ID: {user[0]}, 姓名: {user[1]}, 邮箱: {user[2]}, 年龄: {user[3]}")
# 5. 更新数据
print("\n正在更新 Alice 的年龄...")
update_sql = "UPDATE users SET age = %s WHERE name = %s"
cursor.execute(update_sql, (29, "Alice"))
connection.commit()
print(f"成功更新 {cursor.rowcount} 条数据。")
# 6. 再次查询验证更新
print("\n再次查询 Alice 的信息...")
cursor.execute("SELECT name, age FROM users WHERE name = %s", ("Alice",))
alice_info = cursor.fetchone()
if alice_info:
print(f"Alice 的新年龄是: {alice_info[1]}")
except MySQLdb.Error as e:
print(f"数据库操作出错: {e}")
if connection:
connection.rollback() # 出错时回滚
finally:
# 7. 关闭连接
if connection:
connection.close()
print("\n数据库连接已关闭。")
if __name__ == "__main__":
main()
关闭连接
非常重要! 操作完成后,必须关闭游标和数据库连接,以释放资源。
# 关闭游标 cursor.close() # 关闭数据库连接 db.close()
最佳实践是使用 try...finally 或 with 语句(MySQLdb 的 Connection 对象支持上下文管理器协议)来自动处理关闭操作。
# 使用 with 语句 (推荐)
with MySQLdb.connect(...) as db:
with db.cursor() as cursor:
cursor.execute("...")
# ... 其他操作
# with 块结束时,cursor 会自动关闭
# with 块结束时,db 会自动关闭
总结与对比
| 特性 | MySQLdb |
mysql-connector-python (官方) |
PyMySQL |
|---|---|---|---|
| 兼容性 | 仅 Python 2,安装复杂 | Python 2 & 3,安装简单 | Python 2 & 3,安装简单 |
| 实现语言 | C (高性能) | Python (部分核心用 C) | Python (纯 Python) |
| 安装 | 需要系统依赖 (libmysqlclient-dev) |
pip install mysql-connector-python |
pip install PyMySQL |
| API 风格 | 类似 DB-API 2.0 | 标准 DB-API 2.0 | 标准 DB-API 2.0 |
| 推荐度 | 不推荐用于新项目 | 推荐,特别是官方项目 | 推荐,轻量级,易用 |
| 安全性 | 使用 %s 占位符,安全 |
使用 %s 占位符,安全 |
使用 %s 占位符,安全 |
除非你正在维护一个旧的 Python 2 项目,否则请选择 mysql-connector-python 或 PyMySQL,它们更易于安装、维护,并且与 Python 3 完美兼容。
