Skip to content

Instantly share code, notes, and snippets.

@huyx
Created August 3, 2018 03:55
Show Gist options
  • Save huyx/8c60e781958ec5257fd692478961c795 to your computer and use it in GitHub Desktop.
Save huyx/8c60e781958ec5257fd692478961c795 to your computer and use it in GitHub Desktop.
自动生成 MySQL 数据库文档

数据库文档

自动生成数据库结构文档,文档格式为 Makrdown。

任务

  • 自动生成主文档: 数据表,字段说明
  • 自动生成变更日志
    • 记录数据表的添加、删除
    • 记录字段的添加、删除
  • Markdown 文档发布
    • 目前是发布到 Gitlab 代码库,查看文档时速度比较慢

文档列表

dbdoc 说明

自动生成数据库文档,仅支持 MySQL。

用法:

dbdoc.py -u <username>[:<password>]@<host>:[<port>]/<database> -x <excludes> 

其中:

  • usernamepassword: 用户名,密码
  • host, port: 服务器地址,端口
  • database: 数据库名
  • excludes: 排除指定的表,支持 ? * 等(bash 文件名的规则),多个表达式用 ; 分隔。

举例:

dbdoc.py -u root@localhost/test -x '*_log_*;test_*'
#!/usr/bin/env python3
import argparse
import fnmatch
import sys
from sqlalchemy import create_engine
# 检测 MySQLdb 或 mysql.connector 是否存在
try:
import MySQLdb
except ImportError:
try:
import mysql.connector
except ImportError:
print('MySQLdb and mysql.connector not found.')
sys.exit(1)
else:
mysql_url_template = 'mysql+mysqlconnector://{}?charset=utf8'
else:
mysql_url_template = 'mysql://{}?charset=utf8'
# 模板
DOC_HEADER = '''\
# {dbname}
[[_TOC_]]
'''
TABLE_INFO_TEMPLATE = '''\
## {Name}
{Comment}
'''
COLUMN_HEADER = '''\
| Field | Type | Null | Key | Default | Comment |
| ---- | ---- | ---- | ---- | ---- | ---- |
'''
def execute(statement, *args, **kwargs):
"""封装 engine.execute"""
try:
result = engine.execute(statement, *args, **kwargs)
except Exception as e:
print('Error on execute %r: ' % statement, e)
sys.exit(1)
return result
def filter_exclude(table_name):
"""表名过滤"""
for exclude in args.exclude:
if fnmatch.fnmatch(table_name, exclude):
return True
return False
def print_table(table):
"""输出表相关信息"""
if filter_exclude(table.Name):
return
print(TABLE_INFO_TEMPLATE.format_map(table), end='')
print(COLUMN_HEADER, end='')
for column in execute('SHOW FULL COLUMNS FROM ' + table.Name):
column = dict(column)
column['Comment'] = column['Comment'].replace('\r', '').replace('\n', '<br>')
print('| {Field} | {Type} | {Null} | {Key} | {Default} | {Comment} |'.format_map(column))
print()
def main():
# 分析命令行参数
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', default='root@localhost/test', help='Database URI.')
parser.add_argument('-x', '--exclude', default='', help='Exclude tables(support *, ?).')
global args
args = parser.parse_args()
args.exclude = args.exclude.split(';')
# 连接数据库
global engine
engine = create_engine(mysql_url_template.format(args.url))
# 当前数据库名
dbname = list(execute('SELECT DATABASE()'))[0][0]
print(DOC_HEADER.format(dbname=dbname))
for table in execute('SHOW TABLE STATUS'):
print_table(table)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment