编程 tbls 接进 CI:diff 只比 Markdown,删表残留与 SVG 噪音是两个真坑

2026-11-09 00:03:56

tbls 接进 CI:diff 只比 Markdown,删表残留与 SVG 噪音是两个真坑

CI 里加一条 tbls diff 不等于文档不会漂移。README 原文写得很直白:tbls diff shows the difference Markdown documents only——它比的是 Markdown 文档,不是数据库 schema;而 tbls doc --force 覆盖已有文件时不会删除已删表留下的 md。这两条叠在一起,删表这个动作在 CI 里是静默通过的。

项目: | 文档: | Action: | 发行版:

重新生成的两种模式,决定了 diff 能不能兜底

配置写在 .tbls.yml(或 tbls.yml),dsn + docPath,docPath 默认 dbdoc。

  • tbls doc --force:覆盖已有文档,但不删除已删表遗留的 md 文件。
  • tbls doc --rm-dist:先清空 docPath 再生成。

想让 CI 的 diff 判定有效,就得走 --rm-dist,否则残留文件会一直留在 docPath 里,diff 也不会把它当成差异。--rm-dist 清的是 docPath 指定的目录,改动这个默认值前先确认清空范围。

diff 本身还有两个参数:两库互比用 tbls diff dsnA dsnB;列顺序不一致导致误报时加 --sort。

另外,DSN 上的开关会直接改变生成物内容,从而改变 diff 结果。MySQL 加 ?hide_auto_increment 会隐藏 AUTO_INCREMENT 子句;密码里的 #、= 110——introspection 用到 STRING_AGG和WITHIN GROUP`。数据库迁到新实例、兼容级别还停在 100 时,报错是:

Incorrect syntax near '('

处理:

ALTER DATABASE  SET COMPATIBILITY_LEVEL = 110;

排查时先看兼容级别,别去怀疑 DSN 或驱动版本。

不给 CI 数据库凭据的离线路径

先落一份 schema.json,再基于它生成文档:

tbls out -t json -o schema.json
tbls doc json:///path/to/schema.json

也能直接吃远程地址:tbls doc https://.../schema.json,或 github://owner/repo/path/schema.json。这条路径适合在 PR 里生成文档预览而完全不把库凭据放进 CI。

外部驱动同理:PATH 里有 tbls-driver-foodb 就支持 foodb:// scheme,驱动从环境变量 TBLS_DSN 取 DSN,往 STDOUT 输出 schema.json。

dsn.tls 与原生参数冲突会直接报错

dsn.tls 段支持 ca / cert / key / verify: identity。与原生 DSN 参数冲突时直接报错,而不是静默覆盖,冲突项包括 sslmode=disable、encrypt=disable、trustservercertificate=true、tls=preferred。接 CI 时这意味着同一份 dsn 不能既写原生 TLS 参数又配 dsn.tls,否则第一步就连不上。

GitHub Actions 的两种接法

- uses: k1low/setup-tbls@v1
- run: tbls doc

或者 one-liner 安装:

source  use-tbls.tmp && . ./use-tbls.tmp

循环

tbls doc 提交文档 → 开发周期改 schema → CI 跑 tbls diff / tbls lint → 回到第一步。让这个循环真正闭合的前提是:doc 阶段用 --rm-dist,er 图别留默认 svg。

支持的数据库包括 PostgreSQL / MySQL / MariaDB / SQLite / BigQuery / Cloud Spanner / Redshift / SQL Server / Azure SQL / DynamoDB / Snowflake / MongoDB / ClickHouse / Databricks。

复制全文 生成海报 tbls 数据库文档 CI Go MySQL PostgreSQL

推荐文章

程序员茄子在线接单