最近我用 Golang 开发了一个可以将数据库每张表的各个列信息转化成文档的小工具。开发的缘由是因为写后端时,经常需要为数据库写说明文档,对于稍微有些规模的项目来说,就动辄几十张上百张数据表,开发人员在文档中不断的写各个列的列名、类型、描述实在是无聊、枯燥和苦不堪言。所以就有了这个小工具的诞生。
项目地址在 这里
工具使用介绍
工具用 golang 开发的,所以直接使用 release 的可执行文件就可以, 无需复杂任何编译安装。
1 | dbdoc -c config.json |
在 config.json 文件中,按照格式配置好数据库信息,具体的配置方法如下:
1 | { |
简单两步,就可以自动生成数据库的说明文档了。如下图
展示图中的文档模板是使用工具内置的 markdown 模板
开发过程
整个项目的思路其实非常简单,说起来其实就三步
- 读取数据库的各个表
- 依次读取每个表的列信息
- 将列信息转化成 markdown
虽然步骤简单,但是还是有些值得谈的东西。
数据库适配
目前这个小工具支持 MySQL 和 SQL Server, 这俩数据库在 SQL 语句上有着很大的区别。比如
MySQL 的读取当前数据库下的所有表名的语句是 show tables
,而 SQL Server 的是 SELECT Distinct TABLE_NAME FROM information_schema.TABLES
。除此之外,两个数据库的连接语句,查询列信息的语句,都有很大区别。
所以适配各个数据库,让这个工具支持多个数据库,是件非常复杂的事情。
我目前的做法给每个用到的 SQL 语句做一个工厂方法,给定一个数据库的类型,返回对应的 sql 语句。这种方法虽然复杂繁琐,但是有效。好在我们用到的 SQL 语句也不多,所以效率上也算还好。
目前还在调研各大 ORM 库是怎么实现的这个功能。这个也是以后着重要做的功能。
文档模板
我最初的本意是直接将信息转化成固定的 markdown 格式就可以了,想想既然都提取了表信息为何不做些更自由的做法——用户可以自己定义文档的格式。
比如,这个工具默认生成的格式是这样的:
但是万一用户不想用这个格式,想给每个表格的标题加个编号,或者给每一列加个编号啥的。那这个工具生成的结果就完全没法用了。
不能将我的喜好强加给用户,那么,可以给用户提供足够自由的接口。
所以我提供了一个扩展的做法, 用户可以在配置文件的 template_path
项,配置一个自己定义的文档模板给工具。如果不提供的话,可以使用默认的模板,如下:
1 | {{- .schema}} Document |
这个模板的语法直接用的是 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 作为首选的开发语言。