0%

自动生成数据库文档小工具的诞生

最近我用Golang开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时,经常需要为数据库写说明文档,对于稍微有些规模的项目来说,就动辄几十张上百张数据表,开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。

项目地址在这里

工具使用介绍

工具用golang开发的,所以直接使用release的可执行文件就可以, 无需复杂任何编译安装。

dbdoc -c config.json

在config.json文件中,按照格式配置好数据库信息,具体的配置方法如下:

{
"db_info": {
"db_type": "mysql", // required
"ip_port": "127.0.0.1:3306", // required
"username": "root", // required
"password": "", // required
"schema": "cms" // required
},
"includes": [ // optional
],
"excludes": [ // optional
],
"template_path": "", // optional
"out_path": "" // optional
}

简单两步,就可以自动生成数据库的说明文档了。如下图
展示图

展示图中的文档模板是使用工具内置的markdown模板

开发过程

整个项目的思路其实非常简单,说起来其实就三步

  1. 读取数据库的各个表
  2. 依次读取每个表的列信息
  3. 将列信息转化成markdown

虽然步骤简单,但是还是有些值得谈的东西。

数据库适配

目前这个小工具支持MySQL和SQL Server, 这俩数据库在SQL语句上有着很大的区别。比如
MySQL的读取当前数据库下的所有表名的语句是show tables,而SQL Server的是SELECT Distinct TABLE_NAME FROM information_schema.TABLES。除此之外,两个数据库的连接语句,查询列信息的语句,都有很大区别。
所以适配各个数据库,让这个工具支持多个数据库,是件非常复杂的事情。

我目前的做法给每个用到的SQL语句做一个工厂方法,给定一个数据库的类型,返回对应的sql语句。这种方法虽然复杂繁琐,但是有效。好在我们用到的SQL语句也不多,所以效率上也算还好。

目前还在调研各大ORM库是怎么实现的这个功能。这个也是以后着重要做的功能。

文档模板

我最初的本意是直接将信息转化成固定的markdown格式就可以了,想想既然都提取了表信息为何不做些更自由的做法——用户可以自己定义文档的格式。
比如,这个工具默认生成的格式是这样的:
markdown_preview

但是万一用户不想用这个格式,想给每个表格的标题加个编号,或者给每一列加个编号啥的。那这个工具生成的结果就完全没法用了。
不能将我的喜好强加给用户,那么,可以给用户提供足够自由的接口。

所以我提供了一个扩展的做法, 用户可以在配置文件的template_path项,配置一个自己定义的文档模板给工具。如果不提供的话,可以使用默认的模板,如下:

{{- .schema}} Document
{{range .tables -}}
# {{.TableName}}
|column|type|description|
| ------| ------ | ------ |
{{- range .Columns}}
|{{.ColumnName}}|{{.ColumnType}}|{{.Description -}}|
{{- end}}

{{end}}

这个模板的语法直接用的是golang标准库的text/template, 文档在这里。开始我本来想着随便搜个模板引擎用下,没想到golang直接在标准库里自带了。再次感叹下golang真是为工业化而生。

有了这个文档模板的功能,这个工具的想象空间变得很大。文档的格式不再局限于markdown了,用户可以随便定义文档的格式, html、json都行。当然word的doc格式就是另外一个次元的事情了,我也在考虑是否以后加入进去。

以后要加的功能

  • 支持更多的数据库.
  • 支持导出格式为Word、Excel.
  • 更人性化的命令行接口。目前我为了图省事,就直接传了个-c。后期打算做成MySQL那样直观的接口

谈谈Golang

这个项目是我用Golang做的第一个项目,Golang在这种跨平台小工具,且完全无需考虑安装依赖的情况下是最好的选择了。Golang的熟悉之后用起来几乎和Python一样快速。我在文档模板一节感叹,Golang真是为工业化而生,把很多在其他语言里是三方库的东西直接做到了标准库。但是另一方面,由于Golang中模板和泛型的缺失,有些东西本该内置的又没有了。比如判断一个元素是否在数组中的方法InArray,String的IsBlank方法,都需要用户在项目中再单独写一遍。实在是无法理解

总而言之,如果以后有类似的小工具的需求,我依然会选择Golang或者Python作为首选的开发语言。

cyhone wechat