mcpField
D
dbprint

dbprint

本地服务
jakubro.github.io数据库23 天前更新

关于 dbprint

dbprint 将数据库结构、值分布、关联关系及人工注释保存为仓库中的文本快照,供编码 Agent 离线读取。它通过 MCP 服务、命令行或技能提供上下文,无需让 Agent 连接数据库。

主要功能

  1. 01生成结构与列统计快照
  2. 02记录声明或推断的关联
  3. 03支持人工注释且不覆盖
  4. 04离线提供表级上下文
  5. 05检查快照并用于 CI

适用场景

  1. 01让编码 Agent 在离线环境理解表和字段
  2. 02为生成 SQL 提供值域与关联信息
  3. 03审查数据库快照的结构或数据变化
  4. 04在 CI 中检查快照新鲜度与断言

MCP 相关

dbprint 提供只读 MCP 服务,读取仓库中已提交的快照而不连接数据库;MCP 客户端无需数据库凭据。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"jakubro-dbprint": {
"command": "uvx",
"args": [
"dbprint"
]
}
}
}
启动命令uvx dbprint

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypidbprint0.15.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

dbprint

PyPI Docs License: Apache 2.0 Status M8ven Score

只需在代码旁记录一次数据库的含义,每个 Agent 会话都会读取。

你的编码 Agent 会读取迁移文件和模型,因此能正确了解数据库的结构。但它无法从结构中得知其他信息:revenue_cents 是总额,而每份报表都使用净额列;status 有两种拼写;orders 与 shipments 的一对多联结比任何人预想的都常见;legacy_uid 自迁移后就已废弃。同事只需 30 秒就能告诉它这些信息。没有数据库连接,Agent 无从得知;有了连接,它每个会话都得实时重新发现相同事实——这些查询耗费数据仓库的时间和预算,也消耗 Agent 的令牌——而且它仍可能理解错:计数不会告诉它某个代码已废弃,也不会说明某一列是总额。

dbprint 将这些知识转化为提交到代码库中的纯文本:

  • 只需测量一次数据库。 每个表的 DDL、其联结关系——包括已声明的关系,以及在架构未声明关系时推断出的关系——以及每列的统计信息:空值占比、包含所有拼写形式的完整值列表、范围、分布、值形态等。支持八种数据库引擎。
  • 由 Agent 记录数字的含义。 dbprint annotate 会将一个表的测量结果及其留下的待解问题交给 Agent——某个代码代表什么、某个哨兵日期意味着什么、报表会排除哪些行——Agent 再根据代码和只读查询回答这些问题,并写入 dbprint 永远不会覆盖的文件。dbprint annotate --check 会标记与数据相矛盾的说明。
  • 之后的每个会话都可离线读取。 可通过 MCP 服务、打包的技能或 dbprint context 使用,无需数据库连接,也无需向 Agent 提供凭据。由于内容以文本形式存放在 git 中,架构或数据变更会在审查中显现,dbprint check 还能在 CI 中对其进行把关。

使用 dbprint,Agent 能以更低成本答对更多问题。 在我们针对多个代码库进行的测试中,读取带注释数据打印件的编码 Agent,答错的答案比不读取时少 80%,每个正确答案的成本低 17%;对于只有数据打印件明确说明才能识别的问题,答错的答案更是少 90%。

Agent 会读取的内容

以下摘录自本仓库中参考数据打印件的某个表上的 dbprint context --purpose query,展示了 Agent 编写 SQL 前会收到的内容:

# Table: arboretum.seedbank.germination_trial  (900 rows, 8 columns)

## Joins
- accession_id -> arboretum.seedbank.accession.accession_id (declared)
- collector_id -> arboretum.seedbank.collector.collector_id (inferred)

## Data dictionary

One row per germination attempt run against a batch drawn from an accession.

## Column values

| Column | Values (count) | Coverage | Nulls |
|---|---|---|---|
| medium | 'moist filter paper' (176), 'sterile grit' (176), 'vermiculite mix' (176), 'agar medium' (175), 'sand tray' (176) {'sand tray' (151), 'Sand Tray' (25)}, 'control' (21) = 'No growth medium: a no-treatment control group, its germinated_count compared against ambient conditions rather than a physical medium.' | 100% - the list is the whole domain |  |

这里有三件事是任何迁移文件都不会说明的:medium 仅包含这些值,不含其他值;sand tray 有两种拼写形式,因此按其中一种筛选会漏掉 25 行;control 根本不是一种 medium。前两点由 dbprint 测量得出;第三点由人或 Agent 记录一次,之后每个会话都会读取。

你可以亲自运行,无需数据库,也无需任何配置,只需安装 uv:

uvx dbprint context arboretum.seedbank.germination_trial --purpose query \
  --project https://github.com/jakubro/dbprint/blob/main/docs/format/v1/examples/production/.dbprint.yaml

快速开始

需要 Python 3.13+。请为你的数据库安装对应驱动的额外依赖:

uv tool install 'dbprint[postgres]'     # or [mysql], [snowflake], [duckdb], [clickhouse], [redshift], [databricks], [bigquery]

在同一次安装中添加 [mcp]、[docs] 或 [dbt] 额外依赖——例如 uv tool install 'dbprint[postgres,mcp]'——因为后续安装会替换先前安装的依赖,而不是在其基础上添加。

Postgres 适配器会调用 pg_dump 获取 DDL,因此 PostgreSQL 客户端二进制文件必须位于你的 PATH 中。

在仓库根目录中创建项目骨架:

dbprint init

此操作会写入 .dbprint.yaml(请将其提交到版本库)、创建 prints/,并将凭据模板写入 ~/.dbprint/connections.yaml——该文件位于仓库之外,因此机密信息不会与配置文件放在一起。

在凭据文件中填写连接详情:

# ~/.dbprint/connections.yaml
primary:
  host: localhost
  port: 5432
  database: my_db
  user: dbprint_ro
  password: change_me

并在 .dbprint.yaml 中指定要使用的适配器以及要读取的表:

# .dbprint.yaml
connections:
  primary:
    adapter: postgres
    auto: true
    tables:
      include:
        - "*.public.*"

凭据的解析顺序为:先从 DBPRINT_<CONNECTION>_<KEY> 环境变量读取,其次读取 ~/.dbprint/connections.yaml,最后读取项目根目录下的 .env。这两个文件中的所有键都列在 docs/CONFIG.md 中。

生成数据档案:

dbprint generate

将结果与代码一同提交。之后即使无法连接数据库,也可以检查它:

dbprint list

然后让 Agent 为表添加注释——任务说明包含注释技能中的步骤,因此任何 Agent CLI 都可以照此执行:

dbprint annotate my_db.public.orders | claude -p

并连接你的 Agent来使用结果。

它会对你的数据库做什么

  • 只读。 只需一个可以对你要生成档案的表执行 SELECT 的角色即可;每种引擎的适配器页面都从你的首份数据档案链接到,并列出了确切的授权要求。唯一的写入操作,是临时复制一个抽样表中抽取的行;会话结束时即删除(在 BigQuery 上则会在过期时间到达时删除),且仅在进行抽样时发生——read.tables.materialize 可以将其关闭。
  • 会发布真实值。 值列表、范围和百分位数都是单元格值,会被写入你的仓库。默认情况下不会隐藏任何内容:脱敏会根据列名、检测到的敏感类型(personal_name、national_id……)或数据形态,对这些值进行遮蔽、删除或哈希处理,同时保留所有计数。
  • 只需运行一次数据分析,之后按需重新运行。 当表的数据档案超过新鲜度阈值或其设置发生变化时,才会重新读取该表;在数据仓库上,可以通过抽样、行筛选器和仅读取目录信息来控制成本——参见选择要分析的内容。

数据档案示例

Agent 读取的上下文由普通 YAML 文件组成。以下是同一份参考数据档案中某个表的 statistics.yaml 摘录,部分字段已省略:

row_count: 2500
columns:
  catalogue_url:
    sql_type: character varying(200)
    nullable: false
    null_rate: 0.0
    classification: text
    cardinality: 2500
    cardinality_ratio: 1.0
    inferred:
      looks_like: url
      sampled: 1000
      matched: 1000
      candidate_key: true
    values:
    - value: https://specimens.example.org/accession/1
      count: 1
    - value: https://specimens.example.org/accession/10
      count: 1
    # ... 28 more
    values_coverage: 0.012      # top 30 of 2500 - a value list, not a claim of completeness
    distribution: long_tail

  provenance_country:
    sql_type: character(2)
    classification: categorical
    cardinality: 10
    inferred:
      looks_like: country_code
      sampled: 10
      matched: 10
    values:
    - value: AU
      count: 250
    - value: CA
      count: 250
    - value: DE
      count: 250
    - value: FR
      count: 250
    - value: GB
      count: 250
    # ... 5 more
    values_coverage: 1.0        # the list is the whole domain, not a sample
    distribution: uniform

  received_at:
    sql_type: timestamp(0) with time zone
    classification: temporal
    range:
      min: '2018-01-08T00:00:00Z'
      max: '2024-11-28T00:00:00Z'
      span_days: 2516
    percentiles:
      p01: '2018-02-09T00:00:00Z'
      p25: '2019-10-02T00:00:00Z'
      p50: '2021-06-19T00:00:00Z'
      p75: '2023-03-05T00:00:00Z'
      p99: '2024-10-25T00:00:00Z'

values_coverage: 1.0 是关键字段:这十个值就是该列的完整取值范围,而不只是前十个值。无需查询数据库,就能排除第十一个值。(如果表是基于样本而非全量数据生成档案,覆盖率则根据实际读取的行计算——见下文限定范围的数据分析。)

inferred 是 dbprint 推断出的内容,而不是读取到的内容:looks_like: country_code 是判断结果,sampled/matched 是它的依据,因此,基于十个值确认的形态不会看起来像是基于一万个值确认的。

与之并列的 relationships.yaml 保存了关联关系图:

refers_to:
- column:
  - collector_id
  target_table: arboretum.seedbank.collector
  target_column:
  - collector_id
  on_delete: RESTRICT
  detection: declared      # or `inferred`, when dbprint guessed the edge from naming
  observed:
    fanout_avg: 6.25
    target_coverage: 1.0

这部分是测量所得。另一部分由你编写,放在同一目录中,并在同一次提交中提交——列级注释写在 statistics.annotations.yaml 中:

columns:
  collector_id:
    note: >-
      FK to collector.collector_id. Field collectors are affiliated with a
      partner institution; collector.institution names it.

表级说明则写在 description.md 中,用于记录统计数据无法表达的内容。

dbprint 从不写入这两个文件;它们都会与统计信息一同读取——但对于统计信息能够回答的问题,以统计信息为准;说明文档只对数字无法表达的内容具有权威性。

写入仓库的内容

prints/<connection>/
  manifest.yaml                    # inventory, freshness, per-table thresholds
  reading.md                       # generated guide - how to read the rest of the print
  diff.yaml                        # machine-readable drift from the last run
  manifest.annotations.yaml        # optional, connection-level notes you write
  <schema>/<table>/
    ddl.sql                        # native DDL, normalized for stable diffs
    statistics.yaml                # column distributions
    relationships.yaml             # declared + inferred foreign keys
    description.md                 # optional, you write it
    statistics.annotations.yaml    # optional, per-column notes you write
    relationships.annotations.yaml # optional, per-edge notes you write

每次运行都会重新写入 reading.md:它会告诉使用者哪些字段适用于哪些用途,让从未见过这种格式的 Agent 也能看懂打印结果。

这四个 .md / .annotations.yaml 文件由你管理——dbprint 从不覆盖它们,并且 Agent 阅读的内容中会包含这四个文件。

命令

命令作用
dbprint init创建 .dbprint.yaml、prints/ 和凭据模板
dbprint config explain打印某张表解析得到的配置文件,并为每个值注明其默认值、来源连接或设置它的规则
dbprint generate为数据库生成概要;写入打印结果和 diff.yaml
dbprint list离线汇总已提交的打印结果
dbprint diff将实时数据库与已提交的打印结果进行比较
dbprint checkCI 门禁:检查结构、时效性和统计断言;--online 会额外检查偏差和 SQL 断言
dbprint context输出一个或多个表的适用于提示词的 Markdown 视图
dbprint annotate输出单个表的注释编写指南,或使用 --check 检查注释
dbprint docs以 HTML 网站形式浏览打印结果——可实时 serve,也可静态 build(需安装 [docs] 扩展)
dbprint serve在已提交的打印结果上运行只读 MCP 服务(需安装 [mcp] 扩展)

完整参考:docs/CLI.md。

连接 Agent

MCP 客户端会自行启动服务,因此由客户端(而不是你)选择工作目录。请明确指定项目:

{
  "mcpServers": {
    "dbprint": {
      "command": "uvx",
      "args": ["--from", "dbprint[mcp]", "dbprint", "serve", "--project", "/srv/analytics"]
    }
  }
}

服务会读取已提交的打印结果,且从不连接数据库,因此客户端不需要凭据。

读取远程项目

--project 也接受 Git 地址,因此无需先手动克隆,就能读取提交在他人仓库中的打印结果:

dbprint list --project https://github.com/jakubro/dbprint/blob/main/docs/format/v1/examples/production/.dbprint.yaml
dbprint context arboretum.seedbank.accession --project https://github.com/jakubro/dbprint#main:docs/format/v1/examples/production

dbprint 会为你克隆仓库,且不需要任何自身凭据——访问私有仓库时,你已有的 SSH Agent 或凭据助手即可处理认证。它是只读的:会写入或连接实时数据库的命令(generate、diff、check --online)会拒绝远程定位符;其他所有命令都能像在本地一样对其运行。

超越基础功能

  • 语义推断。 每列都会获得 8 种分类之一。文本、类别和外键列会获得 38 种形态模式之一(uuid、email、phone、ip、country_code……),并公布判定所依据的样本量和匹配数。对于数据不得离开数据库的列,会标注 sensitivity 维度(personal_name、postal_address、national_id、credential……)。唯一性实际上很高(基数比率 >= 0.9999)的列会标记为 candidate_key;只要此阈值纳入的是测得或估算的重复值,而非真正唯一的值,就会同时标记 candidate_key_exception。对于你的架构中未声明的外键,会根据命名进行推断,并标注 detection: inferred。
  • 脱敏。 使用 mask、drop 或 hash(加盐)隐藏单元格值,可按 glob、推断出的敏感度或形态来指定列——因此,明年新增的 personal_name 列也会受到今天编写的规则保护。计数、基数和分布都会保留;只有字面值会被隐藏。盐值与凭据一同保存,绝不会写入已提交的配置。
  • 断言。 使用 YAML 针对任意统计数据编写数据质量检查,也可以直接编写 SQL。统计断言会通过普通的 dbprint check,针对已提交的打印结果进行评估,无需连接数据库;SQL 断言则需要 dbprint check --online。参见 docs/ASSERTIONS.md。
  • CI 退出码。 0 表示正常,1 表示打印结果格式错误或配置不可用,2 表示过时,3 表示存在差异,4 表示连接失败,5 表示运行不完整,6 表示断言失败,7 表示完全失败。diff、check 和 context 都支持 --format json|yaml。
  • 范围化分析。 每表规则可以进行采样(在引擎支持设置种子的情况下,使用表名作为种子)、应用行筛选器,或更改测量内容——并依据表大小设置条件,因此一条规则就能覆盖所有尚未命名的事实表。以这种方式读取的表会包含一个 scope 区块和每列的 rows_scanned;文件中的所有计数都以实际读取的行数为基数,绝不会悄悄按整张表计算。
  • MCP 服务。 dbprint serve 提供 7 个工具——get_table_context、list_tables、search_columns、resolve_value、get_manifest、get_diff、get_reference——并将每个产物作为资源提供。它只读取已提交的打印结果,不会打开数据库连接。参见 docs/MCP.md。
  • Markdown 技能文件。 对于可接收 Markdown 规则或自定义指令的客户端,直接可用的技能文件会告诉 Agent 已提交的打印结果能回答什么问题、应该使用哪个工具回答,以及每个数字涵盖的范围——无需运行任何进程。另一个技能文件则让 Agent 根据写入每张表的代码和只读查询编写注释文件,并使用 dbprint annotate --check 检查。两者都位于 docs/examples/skill/,你可以先阅读,再安装任何内容。
  • dbt 血缘。 将连接的 dbt_manifest 指向已编译的 dbt manifest.json,generate 就会将每个模型列的源列记录为 derived_from,因此,在源列上编写一次的说明就会传递到由该列构建的所有模型([dbt] extra)。参见 docs/CONFIG.md。
  • 令牌预算上下文。 dbprint context arboretum.seedbank.accession --budget 4000 会将 Markdown 视图控制在令牌预算内,并优先移除优先级最低的部分。

最接近的工具

项目功能dbprint 的不同之处
dryrun离线 Postgres 架构快照 + MCP 服务 + lint最接近本项目的工具。它的快照是压缩的二进制包,需要在 .gitattributes 中将其标记为 binary;dbprint 的产物则是可逐行比较的 YAML,具有公开规范,支持八种数据库
dbt-profiler将列配置文件提交为 dbt YAML / Markdown仅支持 dbt 项目。没有 DDL、关系图、语义推断或脱敏功能
实时连接的 MCP 服务(dbhub、postgres-mcp、Supabase、Neon)在 Agent 运行时查询和内省数据库需要 Agent 在每个会话中提供凭据。dbprint 只需生成一次配置文件并提交结果,之后即可在无法连接数据库的情况下提供服务
tbls、SchemaSpy为人类生成架构文档和 ER 图仅包含结构,不含数据分布。dbprint docs serve 会基于 print 中经过测量的列,呈现相同的可浏览页面和 FK 图

dbprint 不是什么

  • 不是迁移工具。 它不会编写、应用或管理 DDL 变更的版本。请使用 Alembic、Flyway、Liquibase、sqldef、Atlas。
  • 不是架构管理或 ORM 层。 print 是从你的数据库生成的;它绝不是你据以构建数据库的事实来源。
  • 不是实时查询接口。 print 中的任何内容都不会为你的 Agent 执行 SQL。
  • 不是数据质量平台。 断言 DSL 是针对 print 的 CI 门禁,不提供监控、告警或血缘功能。请使用 Soda、Great Expectations、Elementary。
  • 不是数据目录。 没有托管服务、共享搜索索引或业务术语表。dbprint docs 会提供已提交 print 的本地只读视图,并绑定到环回地址,无需管理任何内容。

格式

print 是数据库结构及列级数据分布的可移植快照,可提交到 Git,供人类、AI 编码 Agent 和 CI 离线使用。 磁盘上的格式,而非 CLI,才是这里的持久产物:它有明确规范,独立于工具进行版本管理,并且旨在供其他生成工具使用。

格式规范见 docs/format/v1/SPEC.md。

安装包中包含七个 JSON Schemas,位于 src/dbprint/spec/v1/——四个用于生成的产物,三个用于你编写的注释文件;一致性验证器是公开 API,无需数据库、配置或 CLI 即可使用:

from dbprint.conformance import validate_print

issues = validate_print("prints/production")  # conforms iff no error-severity issues

docs/format/v1/examples/ 中的参考 print 是真实的 dbprint 输出,并非手写示例——你在那里看到的就是实际得到的内容。

配置

.dbprint.yaml 保存项目配置(提交到版本库);~/.dbprint/connections.yaml 保存凭据(绝不提交)。两个文件的所有键、类型、默认值和解析顺序,均见 docs/CONFIG.md。内部实现文档见 docs/ARCHITECTURE.md。

许可证

Copyright 2026 Jakub Roman。根据 Apache License 2.0 分发。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。