怎样用脚本批量生成ER图?从零搭建数据库文档流水线
📖 目录导读
- 为什么需要脚本批量生成ER图? —— 痛点与场景分析
- 核心概念:ER图与自动化工具选型
- 实战方案一:基于Python + Graphviz的脚本生成
- 实战方案二:利用SQL解析器 + PlantUML实现多库批量导出
- 进阶技巧:集成CI/CD与版本控制
- 常见问答
- 脚本化ER图的长期收益
为什么需要脚本批量生成ER图?
在传统开发流程中,ER图通常由数据库管理员手动绘制,或依赖Navicat、MySQL Workbench等GUI工具逐表导出,当项目涉及数十张表、跨多个数据库、频繁迭代时,手动维护ER图会面临:

- 时间成本高:每修改一次表结构,需要重新截图或重绘
- 版本混乱:不同开发成员手中有不同版本的ER图
- 缺少关联分析:难以快速展示跨库表关系(如微服务架构)
通过脚本批量生成,你可以一键更新所有ER图,并将其嵌入文档或Wiki中,实现“代码即文档”的自动化效果。
核心概念:ER图与自动化工具选型
1 ER图的两个层级
- 逻辑ER图:描述实体、属性、主外键关系,适合开发沟通
- 物理ER图:包含表名、字段类型、索引、触发器等,适合DBA运维
2 主流自动化工具对比
| 工具 | 输入格式 | 输出格式 | 批量能力 | 学习曲线 |
|---|---|---|---|---|
| Graphviz (DOT语言) | 手动编写DOT | PNG/SVG/PDF | 强(脚本驱动) | 中 |
| PlantUML | 纯文本描述 | PNG/SVG | 强(支持include) | 低 |
| DBML (dbdiagram.io) | DBML语法 | PNG/PDF | 中(需API) | 低 |
| SQLAlchemy + eralchemy | 数据库连接 | PNG | 强(ORM反射) | 中 |
推荐组合:对于大多数场景,PlantUML + SQL解析脚本 是最易上手且可扩展的方案。
实战方案一:基于Python + Graphviz的脚本生成
1 环境准备
pip install graphviz pandas pymysql
2 核心脚本逻辑
from graphviz import Digraph
import pymysql
# 连接数据库
conn = pymysql.connect(host='localhost', user='root', password='pass', db='mydb')
cursor = conn.cursor()
# 查询表及外键关系
cursor.execute("""
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = 'mydb' AND REFERENCED_TABLE_NAME IS NOT NULL
""")
relations = cursor.fetchall()
# 创建ER图
dot = Digraph(comment='ER Diagram', format='png')
for table in set([r[0] for r in relations] + [r[2] for r in relations]):
dot.node(table, table)
for r in relations:
dot.edge(r[0], r[2], label=f"{r[1]} -> {r[3]}")
dot.render('er_diagram', view=True)
3 批量扩展
- 循环数据库列表:读取
config.json中的多个数据库连接串,逐个生成 - 添加字段详情:通过
INFORMATION_SCHEMA.COLUMNS获取字段名和类型,用HTML-like标签嵌入节点
实战方案二:利用SQL解析器 + PlantUML实现多库批量导出
1 为什么选择PlantUML?
- 语法直观:
entity TableName { field1: type <<PK>> } - 支持分页生成:可一次生成跨数据库的ER总图
- 直接嵌入Markdown/Wiki
2 自动生成PlantUML脚本
步骤1:编写Python解析器
import pymysql
def table_to_plantuml(db_name, table_name, cursor):
# 获取字段
cursor.execute(f"DESCRIBE {table_name}")
fields = cursor.fetchall()
# 获取外键
cursor.execute(f"""
SELECT COLUMN_NAME, REFERENCED_TABLE_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA='{db_name}' AND TABLE_NAME='{table_name}'
""")
fks = {row[0]: row[1] for row in cursor.fetchall()}
# 构建entity
lines = [f"entity {table_name} {{"]
for col in fields:
field_name, col_type = col[0], col[1]
pk_mark = " <<PK>>" if col[3] == "PRI" else ""
fk_mark = f" <<FK: {fks[field_name]}>>" if field_name in fks else ""
lines.append(f" {field_name}: {col_type}{pk_mark}{fk_mark}")
lines.append("}")
return "\n".join(lines)
步骤2:批量写入.puml文件
with open("er_diagram.puml","w") as f:
f.write("@startuml\n")
for db in databases:
f.write(f"package {db} {{\n")
for tbl in tables[db]:
f.write(table_to_plantuml(db, tbl, cursor))
f.write("}}\n")
# 添加关系线
f.write("@enduml")
步骤3:一键渲染
plantuml er_diagram.puml -tpng
3 支持跨库关联
在PlantUML中,不同package的实体之间可以直接画线:
package "OrderDB" {
entity Orders
}
package "UserDB" {
entity Users
}
Orders --> Users : user_id
进阶技巧:集成CI/CD与版本控制
1 在Git仓库中自动更新
- 每次提交SQL迁移脚本时,通过Git Hook或GitHub Action自动执行生成脚本
- 对比新旧ER图:使用
git diff或imagemagick compare高亮变更
2 输出为SVG嵌入文档
- Markdown:
 - Confluence:通过REST API上传图片
- Docsify / ReadTheDocs:直接在文档中引用
3 监控数据库变更
- 定时任务(如每天凌晨)运行脚本,生成最新ER图到指定目录
- 若ER图有变化,自动通知团队(邮件、Slack)
常见问答
Q1:脚本生成ER图能处理大数据表(100+字段)吗?
A:可以,建议对字段进行分组显示(如按业务模块),或只显示关键字段(通过配置文件排除created_at等),PlantUML支持hide empty members简化显示。
Q2:如何保证生成的ER图与真实数据库结构一致?
A:脚本直接从INFORMATION_SCHEMA读取,无需中间人,数据库每出现一次变更,只需重新运行脚本即可获得最新图。
Q3:能否生成带索引和注释的详细ER图?
A:可以,在字段后追加<<index>>或<<unique>>,并利用COMMENT属性显示字段注释。
entity User {
id: int <<PK>> <<auto_increment>>
name: varchar(50) <<index>> "用户姓名"
}
Q4:多个团队使用不同的数据库类型(MySQL/PostgreSQL)怎么办?
A:抽象连接层,用一个统一配置读取不同数据库的元信息(pyodbc、psycopg2),所有ER图生成逻辑复用同一份代码。
脚本化ER图的长期收益
使用脚本批量生成ER图,将带来以下不可逆的改变:
- 文档即代码:ER图不再是静态图片,而是随数据库演进而自动更新的活文档
- 团队协作效率提升:新人入职5分钟即可查看全局表关系
- 审计与追溯:通过Git历史可回溯任意版本的数据库结构
- 跨服务治理:在微服务架构中,快速生成统一视图,识别冗余字段或缺失索引
下一步行动建议:
- 选择一个20-50张表的中型项目作为试点
- 编写3小时内的POC脚本(推荐方案二)
- 将脚本加入CI Pipeline,并自动上传至团队文档系统
本文基于实际生产环境经验撰写,已整合多篇公开技术博客(包括掘金、CSDN、Medium)的核心方法,去重后提炼为可落地步骤,若需要完整脚本源码(含多数据库适配),可关注后回复“ER脚本”。