闲不住,手写一个数据库文档生成工具

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。
个人IP:shigen

逛博客的时候,发现了一个很有意思的文章:数据库表结构导出工具。带着好奇,我也去DIY了一个,先看看效果:

实现效果

这个就是主要的程序界面,可以选择生成md文档或者docx文档。具体的文档内容如下:

md文档

md文档内容

docx文档

docx文档

功能可以成功的实现,现在我们来分析一下原理,核心就是几条sql语句:

use security;

show tables;

desc dict;
show full columns from dict where field = 'is_del';

原理分析

查看全部的表

查看全部的表

使用show tables就可以看到当前数据库下边的所有的数据表。

查看表结构

查看表结构

使用desc xxx即可查看表的详细结构,包含字段的全部信息。

查看字段注释

字段的注释需要额外的sql了:

字段注释

当然,shigen也看到过连表查询出字段的注释的,可以进一步的改进。

总结

做一波小总结:其实数据库文档生成,就是用一些sql语句获得对应的表信息和字段信息,使用文本拼接写入到文件里。

代码分享

那本次设计的代码也在这里,欢迎大家学习交流:

from tkinter import *
from tkinter import messagebox

import mysql.connector
from docx import Document
from tabulate import tabulate


# 连接到MySQL数据库
def connect_to_database():
    host = host_entry.get()
    user = user_entry.get()
    password = password_entry.get()
    database = database_entry.get()

    try:
        conn = mysql.connector.connect(host=host,
                                       port=3306,
                                       user=user,
                                       password=password,
                                       database=database)
        return conn
    except mysql.connector.Error as err:
        messagebox.showerror("错误", f"连接到MySQL数据库时出错:{err}")
        return None


# 获取数据库中的表信息及字段注释
def get_table_info(conn):
    tables_info = []
    if conn:
        cursor = conn.cursor()
        cursor.execute("SHOW TABLES")
        tables = cursor.fetchall()
        for table in tables:
            table_name = table[0]
            cursor.execute(f"DESCRIBE {table_name}")
            table_structure = cursor.fetchall()
            tables_info.append({
                "table_name": table_name,
                "structure": table_structure
            })
        cursor.close()
    return tables_info


# 获取字段注释
def get_field_comment(table_name, field_name):
    cursor = conn.cursor()
    cursor.execute(
        f"SHOW FULL COLUMNS FROM {table_name} WHERE Field = '{field_name}'")
    column_info = cursor.fetchone()
    comment = column_info[8]  # 注释信息在第9个元素中
    cursor.close()
    return comment


# 生成Markdown格式的数据库文档
def generate_markdown_documentation(tables_info):
    documentation = "# 数据库文档\n\n"
    documentation += f"数据库地址:{host_entry.get()}\n"
    documentation += f"用户名:{user_entry.get()}\n"
    documentation += f"数据库名称:{database_entry.get()}\n\n"
    for table_info in tables_info:
        table_name = table_info["table_name"]
        structure = table_info["structure"]
        documentation += f"## {table_name}\n\n"
        headers = ["字段", "类型", "允许空值", "键", "默认值", "额外信息", "注释"]  # 添加注释列
        rows = []
        for field_info in structure:
            rows.append(
                list(field_info) +
                [get_field_comment(table_name, field_info[0])])  # 获取字段注释并添加到行中
        documentation += tabulate(rows, headers, tablefmt="pipe") + "\n\n"
    return documentation


# 生成docx格式的数据库文档
def generate_docx_documentation(tables_info):
    doc = Document()
    doc.add_heading('数据库文档', 0)
    doc.add_paragraph(f"数据库地址:{host_entry.get()}")
    doc.add_paragraph(f"用户名:{user_entry.get()}")
    doc.add_paragraph(f"数据库名称:{database_entry.get()}")
    for table_info in tables_info:
        table_name = table_info["table_name"]
        structure = table_info["structure"]
        doc.add_heading(table_name, level=1)

        # 创建带边框的表格
        table = doc.add_table(rows=1, cols=7)
        table.style = 'Table Grid'  # 设置表格样式为带边框的样式
        table.autofit = False  # 禁止自动调整列宽

        hdr_cells = table.rows[0].cells
        hdr_cells[0].text = '字段'
        hdr_cells[1].text = '类型'
        hdr_cells[2].text = '允许空值'
        hdr_cells[3].text = '键'
        hdr_cells[4].text = '默认值'
        hdr_cells[5].text = '额外信息'
        hdr_cells[6].text = '注释'  # 添加注释列
        for field_info in structure:
            row_cells = table.add_row().cells
            row_cells[0].text = field_info[0]
            row_cells[1].text = field_info[1]
            row_cells[2].text = field_info[2]
            row_cells[3].text = field_info[3]
            row_cells[
                4].text = field_info[4] if field_info[4] is not None else ""
            row_cells[5].text = field_info[5]
            row_cells[6].text = get_field_comment(table_name,
                                                  field_info[0])  # 获取并显示字段注释
    return doc


# 创建标签和输入框
def create_input_fields(root, fields):
    entries = {}
    for row, (label_text, entry_text) in enumerate(fields):
        label = Label(root, text=label_text)
        label.grid(row=row, column=0, padx=10, pady=10, sticky="w")
        entry = Entry(root)
        entry.grid(row=row, column=1, padx=10, pady=10)
        entry.insert(0, entry_text)
        entries[label_text] = entry
    # 添加文档类型选择器
    label = Label(root, text="文档类型:")
    label.grid(row=len(fields), column=0, padx=10, pady=10, sticky="w")
    doc_type = StringVar(root)
    doc_type.set("Markdown")  # 默认选择 Markdown
    doc_type_menu = OptionMenu(root, doc_type, "Markdown", "Docx")
    doc_type_menu.grid(row=len(fields), column=1, padx=10, pady=10, sticky="w")
    entries["文档类型:"] = doc_type
    return entries


# 生成文档
def generate_document():
    global conn  # 在函数内部使用全局变量 conn
    conn = connect_to_database()
    if conn:
        tables_info = get_table_info(conn)
        if entries["文档类型:"].get() == "Markdown":  # 获取文档类型
            documentation = generate_markdown_documentation(tables_info)
            with open("数据库文档.md", "w", encoding="utf-8") as file:
                file.write(documentation)
            messagebox.showinfo("成功", "Markdown文档生成成功!")
        elif entries["文档类型:"].get() == "Docx":
            doc = generate_docx_documentation(tables_info)
            doc.save("数据库文档.docx")
            messagebox.showinfo("成功", "Docx文档生成成功!")


# 创建主窗口
root = Tk()
root.title("数据库文档生成器")
root.geometry("400x300")

# 标签和输入框的内容
fields = [("主机地址:", ""), ("用户名:", ""), ("密码:", ""), ("数据库名称:", "")]

# 创建标签和输入框
entries = create_input_fields(root, fields)

# 获取输入框的内容
host_entry = entries["主机地址:"]
user_entry = entries["用户名:"]
password_entry = entries["密码:"]
database_entry = entries["数据库名称:"]

# 生成文档按钮
generate_button = Button(root, text="生成文档", command=generate_document)
generate_button.grid(row=len(fields) + 1, columnspan=2, padx=10, pady=10)

root.mainloop()

与shigen一起,每天不一样!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/550850.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JL-32 土壤速测仪 手持便携可移动 多要素参数可选配

产品概述 土壤速测仪是一款携带方便,操作简单,集采集与存储于一体的可移动式观测仪器。由手持式速测主机、土壤类传感器、USB数据线、电源适配器、便携式手提箱等部分组成。速测仪主机可通过集线器接入不同类型的传感器,互不影响精度&#x…

【二分查找】Leetcode 74. 搜索二维矩阵【中等】

搜索二维矩阵 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则&#xff0c…

记录Python链接mysql数据的增删改查方法

一、添加方法 db pymysql.connect(hostlocalhost,userroot,password123456,dbpython) cursor db.cursor() sql """insert into EMPLOYEEVALUES(3,张,天爱,35,F,8000) """ try:cursor.execute(sql)db.commit() #提交后,数据才会变 …

Springboot+Vue项目-基于Java+MySQL的网上超市系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

Jackson 2.x 系列【28】Spring Boot 集成之 Long 精度损失

有道无术,术尚可求,有术无道,止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址:https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 问题场景2. 原因分析3. 解决方案4. 案例演示4.…

Python 物联网入门指南(七)

原文:zh.annas-archive.org/md5/4fe4273add75ed738e70f3d05e428b06 译者:飞龙 协议:CC BY-NC-SA 4.0 第二十四章:基本开关 到目前为止一定是一段史诗般的旅程!回想一下你开始阅读这本书的时候,你是否曾想象…

v-for中涉及的key

一、为什么要用key? key可以标识列表中每个元素的唯一性,方便Vue高效地更新虚拟DOM;key主要用于dom diff算法,diff算法是同级比较,比较当前标签上的key和标签名,如果都一样,就只移动元素&#…

(十二)C++自制植物大战僵尸游戏多用户存档实现(一)

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs 游戏存档 游戏存档允许玩家保存游戏进度,以便在之后的时间继续游戏。通过存档,玩家可以暂停游戏并在需要时重新开始,而不必从头开始或重新完成已经完成的任务。游戏通常提供多个…

VAR:自回归家族文生图新SOTA,ImageNet上超越Diffusion与DiTs

一、背景: 在人工智能领域,尤其是计算机视觉和自然语言处理中,自回归(AR)大型模型(如GPT系列)因其强大的生成能力和在多种任务上的通用性而受到广泛关注。这些模型通过自监督学习策略&#xff0…

PMP有用吗,PMP含金量,如何转型项目经理?

为什么要学习PMP知识,PMP培训哪家好? IT行业项目管理一枚,曾在做技术的时候对自己的职业发展越来越迷茫,不想干到35岁就参与到失业潮中,一直在想着办法提升自己的能力和竞争力,直到了解到了PMP认证。也就是…

二维码门楼牌管理应用平台建设:场所维护的新篇章

文章目录 前言一、二维码门楼牌管理应用平台的兴起二、民警与网格员的角色定位三、场所信息审核的重要性四、技术支持与创新应用五、未来展望与挑战 前言 随着信息技术的飞速发展,二维码门楼牌管理应用平台的建设正成为城市管理的新宠。该平台不仅提高了场所管理的…

HR招聘人才测评,如何考察候选人的内驱力?

HR的日常招聘工作中,如何去评估候选人的内驱力。人的内驱力,在职业生涯中,是极为重要的品质,也被列入综合素质测评。 内驱力,是指一个人出于内心深处的热情和追求,自发驱动自己持续学习、不断进步&#xf…

jenkins从节点配置说明

目的 打包构建时使用从节点,从节点所在服务器配置4C8G5000G(服务器2) 前提 首先在服务器1上部署jenkins服务,即主节点,默认节点名称为master 步骤 1)登录进入jenkins平台,在系统设置中&…

项目风采展示【车酷-保时捷第二屏】

桌面功能介绍: 1:支持本地app桌面展示 2:支持本地音乐控制

LeetCode 每日一题 Day 123-136

1379. 找出克隆二叉树中的相同节点 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。 其中,克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中,与 tar…

自学Java的第二十四次笔记

一,方法重载 1.基本介绍 java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致! 比如: System.out.println(); out 是 PrintStream 类型 2.重载的好处 1) 减轻了起名的麻烦 2) 减轻了记名的麻烦 3.快速入门案…

git 小记

一、 github新建仓库 git clone 。。。。。。。。。。。 (增删查补,修改) git add . git commit -m "修改” git push (git push main) 二、branch 分支 branch并不难理解,你只要想像将代码拷贝到不同目录…

Modality-Aware Contrastive Instance Learning with Self-Distillation ... 论文阅读

Modality-Aware Contrastive Instance Learning with Self-Distillation for Weakly-Supervised Audio-Visual Violence Detection 论文阅读 ABSTRACT1 INTRODUCTION2 RELATEDWORKS2.1 Weakly-Supervised Violence Detection2.2 Contrastive Learning2.3 Cross-Modality Knowle…

盲人安全导航技巧:科技赋能让出行更自如

作为一名资深记者,长期关注并报道无障碍领域的发展动态。今日,我将聚焦盲人安全导航技巧,探讨这一主题下科技如何赋能视障人士实现更为安全、独立的出行。一款融合了实时避障、拍照识别物体及场景功能的盲人出行辅助应用叫做蝙蝠避障&#xf…

软考 - 系统架构设计师 - Web 应用真题(2)

问题 1: 淘汰策略:遗留系统技术含量低,业务价值也低,所以需要全面重新开发一个系统来替代遗留系;(一般是企业的业务发生了根本变化,遗留系统已经基本不再适应企业运作的需要;或者是遗…