Python导出MySQL数据库的表结构(使用SSH隧道)
1、安装依赖
pip install pymysql pandas openpyxl sshtunnel
2、完整代码
import pymysql import pandas as pd from openpyxl import load_workbook from openpyxl.styles import Border, Side, PatternFill, Font, Alignment from openpyxl.utils import get_column_letter from sshtunnel import SSHTunnelForwarder def sql_to_dataframe(cursor): """将 pyodbc cursor 结果转换为 DataFrame""" # 获取列名 columns = [column[0] for column in cursor.description] # 获取数据并创建DataFrame data = cursor.fetchall() return pd.DataFrame.from_records(data, columns=columns) def get_tables_info(cursor, db_name): """获取所有表信息(含注释)""" query = f""" SELECT TABLE_NAME AS table_name, TABLE_COMMENT AS table_comment FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{db_name}' """ # 执行查询 cursor.execute(query) return sql_to_dataframe(cursor) def get_columns_info(cursor, db_name, table_name): """获取指定表结构详情""" query = f""" SELECT ORDINAL_POSITION AS seq, TABLE_NAME AS table_name, COLUMN_NAME AS column_name, COLUMN_COMMENT AS column_comment, COLUMN_TYPE AS data_type, IF(IS_NULLABLE='YES','[]','[√]') is_nonull FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{db_name}' AND TABLE_NAME = '{table_name}' ORDER BY ORDINAL_POSITION """ # 执行查询 cursor.execute(query) return sql_to_dataframe(cursor) def apply_formatting(excel_path): """应用格式设置""" wb = load_workbook(excel_path) # 定义样式 blue_fill = PatternFill( start_color="0070C0", end_color="0070C0", fill_type="solid" ) thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) for sheet in wb.worksheets: # 设置标题行样式 for cell in sheet[1]: cell.fill = blue_fill cell.font = Font(color="FFFFFF", bold=True) # 设置边框 for row in sheet.iter_rows(min_row=1): for cell in row: cell.border = thin_border # 自适应列宽 for column in sheet.columns: max_length = max( len(str(cell.value)) for cell in column ) adjusted_width = (max_length + 2) * 1.5 sheet.column_dimensions[ get_column_letter(column[0].column) ].width = adjusted_width # 定义居中对齐样式(水平居中 + 垂直居中) alignment = Alignment( horizontal='center', # 水平居中:'left', 'center', 'right', 'justify' vertical='center' # 垂直居中:'top', 'center', 'bottom' ) # 对指定的列设置居中 columns_to_center = ['A', 'F'] for col in columns_to_center: for cell in sheet[col]: cell.alignment = alignment wb.save(excel_path) def add_hyperlinks(excel_path): """添加双向超链接""" wb = load_workbook(excel_path) ws_summary = wb["首页总览"] # 总览表到分表 for row in ws_summary.iter_rows(min_row=2): table_name = row[1].value sheet_name = table_name[:30] hyperlink = f"#'{sheet_name}'!A1" row[1].hyperlink = hyperlink row[1].style = "Hyperlink" # 分表到总览表 for sheet_name in wb.sheetnames[1:]: ws = wb[sheet_name] last_row = ws.max_row + 1 ws.cell(row=last_row, column=1, value="返回\"首页总览\"") ws.cell(row=last_row, column=1).hyperlink = "#'首页总览'!A1" ws.cell(row=last_row, column=1).style = "Hyperlink" wb.save(excel_path) if __name__ == "__main__": # ================== 配置信息 ================== # SSH 隧道配置 ssh_config = { "ssh_address": "100.100.10.10", # SSH服务器地址 "ssh_port": 22, # SSH端口 "ssh_username": "root", # SSH用户名 "ssh_password": "Root@1234", # SSH密码 } # 数据库配置 db_config = { "db_host": "100.100.20.20", # 数据库实际地址(内网地址) "db_port": 3306, # 数据库端口 "db_username": "root", # 数据库用户名 "db_password": "Root@1234", # 数据库密码 "db_name": "testdb" # 数据库名称 } # ================== 建立SSH隧道 ================== try: with SSHTunnelForwarder( (ssh_config["ssh_address"], ssh_config["ssh_port"]), ssh_username=ssh_config["ssh_username"], ssh_password=ssh_config["ssh_password"], remote_bind_address=(db_config["db_host"], db_config["db_port"]) ) as tunnel: local_bind_port = tunnel.local_bind_port print(f"SSH隧道建立成功,本地端口:{local_bind_port}") # ================== 连接数据库 ================== conn = pymysql.connect( host='127.0.0.1', # 这里不要修改 port=local_bind_port, # 这里不要修改 user=db_config['db_username'], password=db_config['db_password'], database=db_config['db_name'], charset='utf8mb4' ) cursor = conn.cursor() print("数据库连接成功!") # 获取所有表信息 df_summary = get_tables_info(cursor, db_config['db_name']) df_summary.insert(0, '序号', range(1, len(df_summary) + 1)) db_name = db_config["db_name"] excel_path = f"数据库{db_name}表结构.xlsx" # 创建Excel写入对象 with pd.ExcelWriter(excel_path, engine='openpyxl') as writer: # 写入总览页 df_summary.to_excel( writer, sheet_name='首页总览', index=False, header=['序号', '表名', '表注释'] ) # 遍历写入各表结构 for _, row in df_summary.iterrows(): table_name = row['table_name'] df_columns = get_columns_info(cursor, db_name, table_name) df_columns.to_excel( writer, sheet_name=table_name[:30], # Excel表名最长31字符 index=False, header=['序号', '表名', '字段名称', '字段注释', '字段类型', '非空'] ) # 应用格式和超链接 add_hyperlinks(excel_path) apply_formatting(excel_path) print(f"表结构已成功导出至 {excel_path}") except Exception as e: print(f"连接失败: {str(e)}") finally: if 'conn' in locals(): conn.close()
本文来自博客园,作者:业余砖家,转载请注明原文链接:https://www.cnblogs.com/yeyuzhuanjia/p/18886185

浙公网安备 33010602011771号