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

news2024/11/27 16:28:40

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一起,每天不一样!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录一下我hive连不上DataGrip的问题

用户名和密码都没问题,但报如下这个错误 原因:是因为我在linux上没启hiveserver2服务 解决: [atguiguhadoop102 hadoop]$ hiveserver2 which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8…

Kotlin从0到1,让你一周快速上手!!

声明 大家好,这里是懒羊羊学长,如果需要pdf版以及其他资料,请加入群聊。群里每天更新面经、求职资料,经验分享等,大家感兴趣可以加一下。 Kotlin 声明1.Kotlin基础2. Kotlin函数3.Kotlin进阶4.Kotlin集合5.Kotlin高…

YOLC: You Only Look Clusters for Tiny Object Detection in Aerial Images

摘要 由于以下因素,从航拍图像中检测物体面临着重大挑战:1)航拍图像通常具有非常大的尺寸,通常有数百万甚至数亿像素,而计算资源有限。2)物体尺寸较小导致有效信息不足,无法进行有效检测。3&am…

numpy的使用

numpy的介绍 numpy是一个python开源的科学计算库 使用numpy可以方便的使用数组、矩阵(列表套列表)进行计算 包括线性代数、傅里叶变换,随机数生成等大量函数 python源代码和numpy和的区别 import numpy as np def func(n):a np.arange(n) *…

JavaEE:HTTP协议

基本内容 网站 后端(HTTP服务器) 前端(浏览器),而后端和前端都需要遵循HTTP协议 HTTP属于超文本传输协议,存在于应用层 文本:一般能在utf8或者gbk上找到的合法字符串 超文本:不仅…

JavaScript基础:js介绍、变量、数据类型以及类型转换

目录 介绍 引入方式 内部方式 外部形式 注释和结束符 单行注释 多行注释 结束符 输入和输出 输出 输入 变量 声明 赋值 关键字 变量名命名规则 常量 数据类型 数值类型 字符串类型 布尔类型 undefined 类型转换 隐式转换 显式转换 Number ✨介绍 &a…

vue3推荐算法

Vue 3 推荐算法主要指的是在 Vue 3 框架中实现的或者适用于 Vue 3 的算法库或组件库。Vue 3 由于其优秀的设计和性能,被广泛应用于构建各种类型的应用程序,包括需要复杂算法支持的项目。以下是一些在 Vue 3 中可能会用到的推荐算法资源: Vue-…

全局视角观看Python备忘录-英文版

全局视角观看Python备忘录-英文版

Java开发从入门到精通(二十):Java的面向对象编程OOP:IO流中的转换流、打印流、数据流、序列流、IO框架

Java大数据开发和安全开发 (一)Java的IO流文件读写1.1 转换流1.1.1 InputStreamReader字符输入转换流1.1.1 OutputStreamWriter字符输出转换流 1.2 打印流1.2.1 PrintStream打印流1.2.2 PrintWriter打印流1.2.3 PrintStream和PrintWriter的区别1.2.4 打印…

FactoryMethod工厂方法模式详解

目录 模式定义实现方式简单工厂工厂方法主要优点 应用场景源码中的应用 模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method 使得一个类的实例化延迟到子类。 实现方式 简单工厂 以下示例非设计模式,仅为编码的一种规…

住宅IP代理和机房IP代理之间的区别?

一、什么是数据中心/机房IP代理? 数据中心/机房IP代理是使用数据中心拥有并进行分配和管理的IP的代理,俗称机房IP代理。 二、数据中心/机房IP代理的特点 与住宅代理通过使用ISP拥有和分配的IP地址的设备路由请求的情况不同,数据中心代理利…

Jenkins上面使用pnpm打包

问题 前端也想用Jenkins的CI/CD工作流。 步骤 Jenkins安装NodeJS插件 安装完成,记得重启Jenkins。 全局配置nodejs Jenksinfile pipeline {agent anytools {nodejs "18.15.0"}stages {stage(Check tool version) {steps {sh node -vnpm -vnpm config…

Linux知识点(3)

文章目录 11. 进程间通信11.1 管道11.1.0 |11.1.1 匿名管道11.1.2 命名管道11.1.3 用匿名管道形成进程池 11.2 system V共享内存11.2.1 system V函数11.2.2 system 命令 11.3 system V消息队列11.4 system V 信号量 12. 进程信号12.1 前台进程和后台进程12.1.1 jobs12.1.2 fg &…

【鸿蒙开发】饿了么页面练习

0. 整体结构 整体划分3部分。店铺部分,购物车部分,金额统计部分。使用 Stack 把3部分堆叠 0.1 整体页面 Index.ets 修改 Index.ets ,使用堆叠布局,并居底部对齐 import { ElShop } from ../components/ElShop import { ElShopp…

数据结构学习之路--深入探索栈的核心要点(附C源码)

哈喽~大家!今天我们来学习栈的特别节目,精彩马上开始~ 目录 前言 一、栈 1 栈的概念 2 栈的结构 3 栈的实现 3.1 栈的定义 3.2 栈的初始化 3.3 入栈 3.4 出栈 3.5 取栈顶元素 3.6 判断栈是否为空 3.7 栈的大小 3.8 栈的销毁 二、源代…

MES系统功能有什么?对企业有什么价值?

制造业为什么上MES: MES最核心的东西是对生产进行管控,实现生产工厂的透明化、实时化、可控化、可追溯化。 上MES的目的: 最为根本的目的是可以对生产当中的质量进行管控,对交期进行管理,对成本进行控制,…

Java SDK 使用示例

我们使用同样的 Maven 模板去创建 use-test-sdk 项目,不同的是,我们需要在 use-tset-sdk 下创建一个 lib 文件夹,用来存放 test-sdk.jar 文件。 我们将 test-sdk.jar 拖放到 use-test-sdk/lib 下,然后我们就可以编写代码了&#…

47.HarmonyOS鸿蒙系统 App(ArkUI)创建轮播效果

创建轮播效果,共3页切换 Entry Component struct Index {State message: string Hello Worldprivate swiperController: SwiperController new SwiperController()build() {Swiper(this.swiperController) {Text("第一页").width(90%).height(100%).bac…

Appium Desktop + Appium Inspector + 模拟器连接

一、环境预备 1.你需要安装好配置好adb,确保可以在命令行直接运行adb指令 2.安装Appium Desktop、Appium Inspector 、 模拟器 二、启动appium 服务 启动后,画面如下: 三、启动模拟器 此时,启动模拟器,打开电脑cmd窗口&#x…

记第一次踩坑Gradle

今天有个项目只能使用Gradle编译,没办法了,尝试吧。 先去下载了最新版本的Gradle,然后配置好了环境变量,可以在命令行使用gradle命令了。 然后打开项目开始操作一番,但是上来就傻眼了。 我白下载了,又重新下…