怎样用脚本批量生成ER图?

wen 实用脚本 4

怎样用脚本批量生成ER图?从零搭建数据库文档流水线

📖 目录导读

  1. 为什么需要脚本批量生成ER图? —— 痛点与场景分析
  2. 核心概念:ER图与自动化工具选型
  3. 实战方案一:基于Python + Graphviz的脚本生成
  4. 实战方案二:利用SQL解析器 + PlantUML实现多库批量导出
  5. 进阶技巧:集成CI/CD与版本控制
  6. 常见问答
  7. 脚本化ER图的长期收益

为什么需要脚本批量生成ER图?

在传统开发流程中,ER图通常由数据库管理员手动绘制,或依赖Navicat、MySQL Workbench等GUI工具逐表导出,当项目涉及数十张表、跨多个数据库、频繁迭代时,手动维护ER图会面临:

怎样用脚本批量生成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 diffimagemagick compare高亮变更

2 输出为SVG嵌入文档

  • Markdown![ER图](er_diagram.svg)
  • 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:抽象连接层,用一个统一配置读取不同数据库的元信息(pyodbcpsycopg2),所有ER图生成逻辑复用同一份代码。


脚本化ER图的长期收益

使用脚本批量生成ER图,将带来以下不可逆的改变:

  • 文档即代码:ER图不再是静态图片,而是随数据库演进而自动更新的活文档
  • 团队协作效率提升:新人入职5分钟即可查看全局表关系
  • 审计与追溯:通过Git历史可回溯任意版本的数据库结构
  • 跨服务治理:在微服务架构中,快速生成统一视图,识别冗余字段或缺失索引

下一步行动建议

  1. 选择一个20-50张表的中型项目作为试点
  2. 编写3小时内的POC脚本(推荐方案二)
  3. 将脚本加入CI Pipeline,并自动上传至团队文档系统

本文基于实际生产环境经验撰写,已整合多篇公开技术博客(包括掘金、CSDN、Medium)的核心方法,去重后提炼为可落地步骤,若需要完整脚本源码(含多数据库适配),可关注后回复“ER脚本”。

抱歉,评论功能暂时关闭!