- 直接调用系统命令:使用
subprocess模块,这种方式最直接,可以完全复现你在命令行中执行mysqldump的所有操作,包括将输出保存到文件。 - 使用 Python MySQL 库:使用如
PyMySQL或mysql-connector-python这样的库,这种方式更“Pythonic”,可以直接在代码中操作数据库对象,生成数据,然后将其写入文件,它不依赖系统是否安装了mysqldump客户端。
下面我将详细介绍这两种方法,并提供完整的代码示例。

使用 subprocess 模块(推荐,最直接)
这种方法的核心是使用 Python 的 subprocess 模块来启动一个新的进程,并执行 mysqldump 命令。
优点
- 简单直接:命令与你在终端中输入的基本一致。
- 功能完整:可以利用
mysqldump的所有参数和选项(如--single-transaction,--routines,--triggers等)。 - 性能高:
mysqldump是一个高度优化的二进制程序,直接调用它通常比用 Python 逐条查询数据再格式化要快得多。
缺点
- 依赖外部程序:运行此脚本的机器必须安装了 MySQL 客户端,
mysqldump可在系统路径中找到。 - 平台相关:在不同操作系统(Windows, Linux, macOS)上,命令的路径和可能略有不同。
代码示例
这个例子演示了如何连接到 MySQL 数据库,并将 my_database 数据库的所有数据备份到一个 SQL 文件中。
import subprocess
import os
# --- 配置信息 ---
# 数据库连接信息
db_host = 'localhost'
db_user = 'your_username'
db_password = 'your_password'
db_name = 'my_database'
# 备份文件路径
backup_file_path = '/path/to/your/backup.sql' # 请确保此目录存在且有写权限
# --- 执行备份 ---
try:
# 构建 mysqldump 命令
# 注意:密码参数 -p 后面不要直接跟密码,而是让 mysqldump 在执行时提示输入。
# 这样更安全,避免密码出现在命令历史或进程列表中。
# 如果必须直接写在命令里,格式为:-p'your_password' (注意没有空格)
command = [
'mysqldump',
f'-h{db_host}',
f'-u{db_user}',
f'-p{db_password}', # 直接跟密码,不安全,仅用于演示
db_name
]
# 使用 subprocess.run 执行命令
# check=True 会在命令返回非零退出码(即失败)时抛出 CalledProcessError 异常
# capture_output=True 会捕获标准输出和标准错误
# text=True 会将输出解码为文本
result = subprocess.run(
command,
check=True,
capture_output=True,
text=True
)
# 将捕获到的标准输出(即 SQL 语句)写入备份文件
with open(backup_file_path, 'w', encoding='utf-8') as f:
f.write(result.stdout)
print(f"数据库 '{db_name}' 备份成功!")
print(f"备份文件已保存至: {os.path.abspath(backup_file_path)}")
except subprocess.CalledProcessError as e:
print(f"执行 mysqldump 时发生错误!")
print(f"错误码: {e.returncode}")
print(f"标准错误输出: {e.stderr}")
except FileNotFoundError:
print("错误:未找到 'mysqldump' 命令,请确保 MySQL 客户端已安装并添加到系统 PATH 中。")
except Exception as e:
print(f"发生未知错误: {e}")
更安全的密码处理方式(推荐):
不要将密码直接写在命令行中,你可以让 mysqldump 从配置文件中读取,或者通过环境变量传递。

import subprocess
import os
# ... (db_host, db_user, db_name, backup_file_path 配置同上) ...
# 方法1:使用配置文件 (my.cnf)
# 在 ~/.my.cnf 文件中添加:
# [client]
# user=your_username
# password=your_password
# host=localhost
# 然后命令可以简化为:
command = ['mysqldump', db_name]
# 方法2:使用环境变量 (推荐)
os.environ['MYSQL_PWD'] = 'your_password' # 设置环境变量
command = ['mysqldump', f'-h{db_host}', f'-u{db_user}', db_name]
try:
result = subprocess.run(
command,
check=True,
capture_output=True,
text=True
)
with open(backup_file_path, 'w', encoding='utf-8') as f:
f.write(result.stdout)
print(f"数据库 '{db_name}' 备份成功!")
except subprocess.CalledProcessError as e:
print(f"执行 mysqldump 时发生错误!\n{e.stderr}")
except FileNotFoundError:
print("错误:未找到 'mysqldump' 命令。")
使用 Python MySQL 库(更 Pythonic)
这种方法不依赖 mysqldump,而是通过 Python 库连接数据库,获取表结构(SHOW CREATE TABLE)和数据(SELECT),然后将它们组合成 SQL 格式并写入文件。
优点
- 平台无关:只要有 Python 和相应的库即可运行,无需安装 MySQL 客户端。
- 代码集成度高:可以轻松地将备份逻辑集成到更大的 Python 应用中,并对数据进行预处理。
- 灵活性高:可以完全控制 SQL 生成的格式。
缺点
- 性能较低:对于大型数据库,逐条查询和格式化数据会比
mysqldump慢很多。 - 实现复杂:需要自己处理表结构、数据转义、外键约束等各种细节,容易出错。
代码示例
这个例子使用 PyMySQL 库来实现备份功能。
安装 PyMySQL:
pip install pymysql
Python 代码:

import pymysql
import os
# --- 配置信息 ---
db_host = 'localhost'
db_user = 'your_username'
db_password = 'your_password'
db_name = 'my_database'
backup_file_path = '/path/to/your/backup_pymysql.sql'
def backup_database_with_pymysql():
"""使用 PyMySQL 库备份数据库"""
try:
# 1. 连接到数据库
connection = pymysql.connect(
host=db_host,
user=db_user,
password=db_password,
database=db_name,
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
with connection.cursor() as cursor:
# 2. 获取所有表名
cursor.execute("SHOW TABLES")
tables = cursor.fetchall()
table_names = [list(t.values())[0] for t in tables]
# 3. 打开备份文件
with open(backup_file_path, 'w', encoding='utf-8') as f:
# 4. 写入数据库版本信息和备份声明
f.write(f"-- MySQL backup for database '{db_name}'\n")
f.write(f"-- Backup generated on: {pymysql.__version__}\n\n")
for table_name in table_names:
# 5. 导出表结构
cursor.execute(f"SHOW CREATE TABLE `{table_name}`")
create_table_sql = cursor.fetchone()
f.write(f"{create_table_sql['Create Table']};\n\n")
# 6. 导出表数据
cursor.execute(f"SELECT * FROM `{table_name}`")
rows = cursor.fetchall()
if rows:
# 获取列名
columns = [key for key in rows[0].keys()]
# 构建 INSERT INTO ... VALUES (...) 语句
insert_sql = f"INSERT INTO `{table_name}` ({', '.join([f'`{col}`' for col in columns])}) VALUES "
for row in rows:
values = [repr(str(val)) for val in row.values()] # repr() 可以处理转义字符
f.write(f"{insert_sql}({', '.join(values)});\n")
f.write("\n")
print(f"数据库 '{db_name}' 使用 PyMySQL 备份成功!")
print(f"备份文件已保存至: {os.path.abspath(backup_file_path)}")
except Exception as e:
print(f"使用 PyMySQL 备份时发生错误: {e}")
finally:
if 'connection' in locals() and connection.open:
connection.close()
# --- 执行备份 ---
backup_database_with_pymysql()
总结与选择建议
| 特性 | subprocess 调用 mysqldump |
Python MySQL 库 |
|---|---|---|
| 依赖性 | 需要系统安装 mysqldump |
仅需 Python 库 (PyMySQL) |
| 性能 | 非常高,推荐用于生产环境 | 较低,不适合大型数据库 |
| 易用性 | 简单,命令直观 | 实现复杂,需处理细节 |
| 灵活性 | 依赖 mysqldump 的功能 |
完全自定义,可对数据进行操作 |
| 适用场景 | 常规数据库备份、数据迁移 | 需要在 Python 应用中精细控制备份逻辑、小型数据库备份 |
如何选择?
- 如果你只是需要一个简单、快速、可靠的数据库备份脚本,强烈推荐使用
subprocess方法,这是行业标准做法,性能和稳定性都最好。 - 如果你的应用是一个 Python Web 服务(如 Django/Flask),并且你希望在不依赖系统工具的情况下实现备份功能,或者需要在备份前对数据进行一些处理,可以考虑使用 Python 库方法,但对于大型项目,性能会是瓶颈。
