sqlacodegen 可从数据库反向生成可信 SQLAlchemy 模型,是 ER 图和版本比对的唯一可靠基础;需确保外键存在、用 --noclasses 和 YAML 格式输出,结合 eralchemy 与 mermaid 实现可 diff、可 CI 自动更新的文本化 ER 图。
用 sqlacodegen 从现有数据库反向生成 ER 图基础结构
直接读库比看文档靠谱,尤其当表字段命名混乱、外键缺失或注释为零时。sqlacodegen 能把真实表结构转成带关系的 sqlalchemy 模型,这是后续绘图和版本比对的唯一可信源。
常见错误现象:sqlacodegen 报 KeyError: 'foreign_keys' 或漏掉关联关系——本质是数据库里没建外键约束,工具只能靠命名猜(比如 user_id 字段自动连 users.id),但一猜就错。
- 必须先确认数据库中已定义外键:
SELECT constraint_name, constraint_type FROM information_schema.table_constraints WHERE table_name = 'xxx'; - 生成时加
--noclasses参数输出纯表定义(避免 SQLAlchemy 类名干扰协作理解) - 导出为 YAML 更利于 diff:用
sqlacodegen --outfile schema.yaml --format yaml postgresql://...
用 dbdiagram.io 或 mermaid 渲染可共享的 ER 图
截图或 PNG 不进 Git,没法做版本对比;手动画图又跟不上表变更节奏。真正能协同的图,得是文本格式、能 diff、能 CI 自动更新。
使用场景:PR 提交新表时,自动在评论里附上变更前后 mermaid ER 片段;团队成员点开链接就能看实时图,不用装客户端。
-
dbdiagram.io支持上传 SQL DDL 文件生成在线图,但不支持版本回溯 —— 仅适合临时分享 - 更稳的做法:用
eralchemy把schema.yaml转成mermaid代码,再用 GitHub 插件(如mermaid-cli)渲染为 SVG 提交到仓库 - 注意
eralchemy默认忽略无外键的“逻辑关联”,需手动补--include-tables列表防止漏表
Git 中管理 ER 图元数据的关键路径与冲突处理
图本身不是重点,图对应的结构定义才是。把 schema.yaml 和生成的 er.mmd(mermaid 源码)一起提交,才能让每次 git diff 显示“删了 user_profile 表”或“给 orders 加了 status_idx 索引”。
容易踩的坑:多人同时改同一张表,schema.yaml 合并后字段顺序错乱,eralchemy 渲染时报 AttributeError: 'NoneType' object has no attribute 'name'。
- 约定所有字段按字母序排列(用
yq工具预处理:yq eval '(.tables[] | .columns) |= sort_by(.name)' schema.yaml) - 禁止直接编辑生成的
er.mmd—— 它只是衍生产物,只允许通过重跑脚本更新 - 在
.gitattributes里标记*.mmd merge=ours,避免合并时污染图形源码
对接 CI/CD 实现 ER 图自动更新与变更拦截
没人会记得每次改完库就手动跑一遍图生成。把这件事塞进 CI,既省事又能卡住高危操作,比如删除主键、改列类型不兼容。
性能影响很小:一次全量生成耗时通常 ALTER TABLE users DROP COLUMN id 这种毁灭性误操作。
- 在 CI 的
before_script阶段拉取最新库结构,对比上一个 commit 的schema.yaml,有差异才触发渲染 - 用
diff -u比对前后 YAML,grep 出- columns:或+ primary_key:行,作为 PR 描述自动填充 - 关键拦截项写进脚本:如果检测到
type: INTEGER变成type: VARCHAR,直接 exit 1 并提示“列类型降级需 DBA 审批”
最常被忽略的是时间戳字段的隐式行为——created_at TIMESTAMP WITH TIME ZONE 在不同环境可能被简化为 TIMESTAMP,导致 sqlacodegen 生成的模型丢失时区语义,ER 图里看不出这个差异,但应用层会出 bug。










