import pymysql
from typing import List, Dict, Tuple
import os
class MySQLTableExporter:
def __init__(self, host: str, port: int, user: str, password: str, db_name: str):
"""
初始化数据库连接
:param host: 数据库主机
:param port: 数据库端口
:param user: 数据库用户名
:param password: 数据库密码
:param db_name: 要导出的数据库名
"""
self.host = host
self.port = port
self.user = user
self.password = password
self.db_name = db_name
self.conn = None
self.cursor = None
# 新增:定义需要忽略的表前缀列表
self.ignore_prefixes = ['jimu_', 'onl_', 'qrtz_', 'rep_demo', 'test_','jeecg_','demo']
def connect(self) -> None:
"""建立数据库连接"""
try:
self.conn = pymysql.connect(
host=self.host,
port=self.port,
user=self.user,
password=self.password,
db=self.db_name,
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
self.cursor = self.conn.cursor()
print(f"成功连接到数据库:{self.db_name}")
except Exception as e:
raise ConnectionError(f"数据库连接失败:{str(e)}")
def get_all_tables(self) -> List[str]:
"""获取数据库中所有表名(过滤掉指定前缀的表)"""
try:
sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = %s ORDER BY TABLE_NAME"
self.cursor.execute(sql, (self.db_name,))
all_tables = [item['TABLE_NAME'] for item in self.cursor.fetchall()]
# 新增:过滤掉指定前缀的表
filtered_tables = []
for table in all_tables:
# 检查表名是否以忽略前缀开头
if not any(table.startswith(prefix) for prefix in self.ignore_prefixes):
filtered_tables.append(table)
else:
print(f"忽略表:{table}(匹配前缀{[p for p in self.ignore_prefixes if table.startswith(p)][0]})")
return filtered_tables
except Exception as e:
raise Exception(f"获取表名失败:{str(e)}")
def get_table_cn_name(self, table_name: str) -> str:
"""
获取表的中文名称(优先数据库注释→预定义映射→英文表名)
:param table_name: 英文表名
:return: 表的中文名称(无则返回英文表名)
"""
try:
# 1. 先从数据库获取表注释(优先使用)
sql = """
SELECT TABLE_COMMENT
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s
"""
self.cursor.execute(sql, (self.db_name, table_name))
result = self.cursor.fetchone()
db_comment = result['TABLE_COMMENT'] if result and result['TABLE_COMMENT'] else ""
if db_comment:
return db_comment
# 2. 数据库无注释时,使用预定义的中文映射
predefined_cn_names = {
"delegation_mode": "委托方式表",
"active_arrange_order": "活动安排表",
"review_condition": "评审条件表",
"study_certificate": "学习管理证书表"
# 可在此添加其他表的中文映射(键:英文表名,值:中文表名)
}
return predefined_cn_names.get(table_name, table_name)
except Exception as e:
raise Exception(f"获取表{table_name}中文名称失败:{str(e)}")
def get_table_columns(self, table_name: str) -> List[Dict]:
"""获取表的列信息(字段名、类型、主键、非空、注释等)"""
try:
sql = """
SELECT
COLUMN_NAME AS 代码,
COLUMN_NAME AS 名称, -- 若字段有中文名称可修改此处查询逻辑
COLUMN_TYPE AS 数据类型,
CASE WHEN COLUMN_KEY = 'PRI' THEN 'TRUE' ELSE 'FALSE' END AS 主要的,
CASE WHEN IS_NULLABLE = 'NO' THEN 'TRUE' ELSE 'FALSE' END AS 强制,
COLUMN_COMMENT AS 注释
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s
ORDER BY ORDINAL_POSITION
"""
self.cursor.execute(sql, (self.db_name, table_name))
columns = self.cursor.fetchall()
return columns
except Exception as e:
raise Exception(f"获取表{table_name}列信息失败:{str(e)}")
def generate_markdown(self, tables: List[str]) -> str:
"""生成Markdown格式的文档内容(核心:只保留三级标题「表 中文(英文)」)"""
# 1. 表清单部分(完全还原原始模板格式)
markdown_content = "# 1表清单\n\n## 1.1表清单\n\n"
markdown_content += "|名称|代码|注释|\n|---|---|---|\n"
for table in tables:
table_cn_name = self.get_table_cn_name(table)
# 名称列显示中文(无则英文),代码列英文表名,注释列与名称列一致
markdown_content += f"|{table_cn_name}|{table}|{table_cn_name}|\n"
# 2. 表列清单部分(核心改动:只保留三级标题,格式为「表 中文名称(英文表名)」)
markdown_content += "\n# 2表列清单\n\n"
for table in tables:
columns = self.get_table_columns(table)
table_en_name = table # 英文表名
table_display_name = self.get_table_cn_name(table) # 中文(无则英文)
# 只保留三级标题:### 表 中文名称(英文表名)(完全匹配要求)
markdown_content += f"### {table_display_name}({table_en_name})\n\n"
# 列清单表格(完全还原原始模板:代码列带,列结构一致)
markdown_content += "|代码|名称|数据类型|主要的|强制|注释|\n"
markdown_content += "|---|---|---|---|---|---|\n"
for col in columns:
markdown_content += (
f"|{col['代码']}|{col['名称']}|{col['数据类型']}|"
f"{col['主要的']}|{col['强制']}|{col['注释'] or ''}|\n"
)
markdown_content += "\n" # 表之间空行,优化可读性
return markdown_content
def export(self, output_file: str = "数据库表结构文档.md") -> None:
"""执行导出操作"""
try:
self.connect()
tables = self.get_all_tables()
if not tables:
print("数据库中没有找到符合条件的表(已过滤指定前缀表)")
return
markdown_content = self.generate_markdown(tables)
# 写入文件
with open(output_file, 'w', encoding='utf-8') as f:
f.write(markdown_content)
print(f"导出成功!共导出{len(tables)}张表,文件保存至:{os.path.abspath(output_file)}")
except Exception as e:
print(f"导出失败:{str(e)}")
finally:
# 关闭连接
if self.cursor:
self.cursor.close()
if self.conn:
self.conn.close()
if __name__ == "__main__":
# -------------------------- 配置参数 --------------------------
CONFIG = {
"host": "localhost", # 数据库主机(默认localhost)
"port": 3306, # 数据库端口(默认3306)
"user": "root", # 数据库用户名
"password": "root",# 数据库密码
"db_name": "db-name" # 要导出的数据库名
}
# -------------------------- 配置参数 --------------------------
# 创建导出实例
exporter = MySQLTableExporter(
host=CONFIG["host"],
port=CONFIG["port"],
user=CONFIG["user"],
password=CONFIG["password"],
db_name=CONFIG["db_name"]
)
# 执行导出(可指定输出文件名)
exporter.export(output_file="数据库表结构文档.md")
python实现将mysql数据表导出指定格式的文档
最新推荐文章于 2026-07-02 10:43:35 发布
1173

被折叠的 条评论
为什么被折叠?



