DBJoy:面向 macOS 的开源 AI 优先 PostgreSQL 客户端
Show HN: DBJoy – An open-source AI-first PostgreSQL client for macOS
DBJoy 是一款面向 macOS 的开源 AI 优先 PostgreSQL 客户端,用户可用自然语言提问,由 AI 助手查询表结构并执行真实查询作答,或直接生成 SQL,需自备 Anthropic 或 OpenAI API key。
██████╗ ██████╗ ██╗ ██████╗ ██╗ ██╗ ██╔══██╗██╔══██╗ ██║██╔═══██╗╚██╗ ██╔╝ ██║ ██║██████╔╝ ██║██║ ██║ ╚████╔╝ ██║ ██║██╔══██╗██ ██║██║ ██║ ╚██╔╝ ██████╔╝██████╔╝╚█████╔╝╚██████╔╝ ██║ ╚═════╝ ╚═════╝ ╚════╝ ╚═════╝ ╚═╝
面向 Mac 的 AI 优先 PostgreSQL 客户端。用自然语言询问你的数据,获得由真实查询支撑的答案,或让它为你编写 SQL,使用你自己的 Anthropic 或 OpenAI 密钥。然后浏览模式、安全地编辑数据、编写 SQL 并导出,全部在一个快速、键盘友好的 SwiftUI 应用中完成。更多数据库引擎可作为驱动添加。
安装
从 Releases 下载最新的 DBJoy-<version>.dmg,打开它,然后将 DBJoy 拖到 Applications 中。构建版本使用 Developer ID 签名,并由 Apple 公证。
- macOS 15 或更高版本,Apple Silicon
- 自包含:libpq 和 pg_dump(用于备份)随应用一起提供
功能
AI 助手
- 用自然语言询问你的数据(⌘J):助手会查找表结构、运行查询,并以内联方式在聊天中显示结果
- 让它编写 SQL,它会在新标签页中打开查询,供你查看、运行或保存
- 聊天按连接自动保存;重新打开一个即可从上次中断处继续,并可在文件夹中整理它们(将聊天拖到文件夹上,或使用其上下文菜单重命名、移动或删除)
- 使用你自己的 Anthropic 或 OpenAI API 密钥(设置 → AI 助手);密钥存储在 macOS 钥匙串中,模型可配置
- 默认只读:其查询在只读事务中运行。打开 允许助手更改数据 以允许它运行 INSERT/UPDATE/DELETE 和模式更改,每个都在一个事务中执行,并在每次更改前有批准步骤(生产连接上始终开启;只读连接上从不开启)
Claude Code 和其他 MCP 客户端
- 从任何项目向 Claude Code 询问你的数据:DBJoy 通过 MCP 共享你选择的连接,因此 Claude Code 可以使用 DBJoy 保存的密码和 SSH 隧道查找表并运行只读查询。 参见 从 Claude Code 使用 DBJoy
连接
- 保存的连接按文件夹分组,并按环境标记:本地、开发、测试、预发布、生产
- 粘贴连接字符串(
postgres://user:pass@host:5432/db?sslmode=require或host=… dbname=…)以填写新连接;DBJoy 还会提供它在剪贴板上找到的连接 - 密码存储在 macOS 钥匙串中;支持 SSL 模式
- SSH 隧道:通过 SSH 服务器(代理、私钥或密码认证)访问网络中被阻止端口的数据库。在连接表单中设置,或直接从“无法连接”屏幕设置
- 只读连接,由服务器强制执行
- 每个连接在自己的窗口中打开,可以同时打开多个
- 从内置图标包中为每个连接指定一个图标(或保留其首字母),显示在其环境的柔和色彩上
- 星标连接以将其固定到每个窗口左侧的可折叠栏;单击即可将该窗口切换到该连接(或根据设置打开新窗口;⌘-单击则相反)
浏览
- 数据库和模式切换器;表、视图、物化视图、外部表、函数和过程
- 模糊侧边栏搜索,以及 ⌘P 打开所有模式中的任何对象
- 每个表的关系视图(出站和入站外键、依赖视图)以及模式范围的 ER 图
数据
- 分页网格,支持列排序、用于长值的行详情面板,以及复制为 TSV 或 INSERT
- 批量编辑:选择多行并打开 行详情 以一次更改所有行上的某个字段
- ⌘F 按字段和运算符搜索(包含、等于、范围、IN、IS NULL、原始 SQL……),结果可编辑
- 从外键值跳转到它引用的行
安全编辑
- 编辑会暂存并以颜色编码:已修改、已插入、已删除
- ⌘S 在一个事务中提交所有内容;每条语句必须恰好影响一行,否则整批回滚
- 布尔值、枚举类型和
CHECK (col IN (...))列表使用下拉编辑器;生成列是只读的 - SQL 函数作为值:在日期、数字或 UUID 单元格中输入
NOW()、CURRENT_DATE或gen_random_uuid()类型,或在任意单元格开头输入=表示表达式(=now() + interval '1 day'、=upper('x'));服务器在提交时计算该值。输入\=可存储以=开头的文本 - 没有主键的表是只读的
- 在生产连接上,每次写入都会显示其 SQL 以供审查并要求确认;drop 和 truncate 始终会确认
结构
- 编辑列(名称、类型、可空性、默认值、注释)、索引、约束和外键
- 创建表
- 更改以审查过的
ALTER语句在一个事务中运行
SQL 编辑器
- 语法高亮、行号,以及能识别表别名的补全
- ⌘↩ 运行光标处或选中的语句,⇧⌘↩ 运行全部,⌘. 取消
- 多个结果集、服务器通知,以及会移动光标的错误位置
- 每个查询标签页都有自己的连接,带有 Begin / Commit / Rollback 和实时事务指示器
- 已保存的查询(按连接或共享)和按连接的历史记录
- 打开
.sql文件(⌘O,或将它们拖到查询标签页上)并可选地立即运行;Run SQL File…(⇧⌘O)一步打开并运行。诸如\connect或\copy之类的 psql 专用命令会在任何内容运行之前被标记出来
架构比较与迁移
- 比较两个数据库之间的架构,例如开发环境与生产环境(Database → Compare Schemas…,⇧⌘D):表、列、键、索引、检查约束、视图、物化视图、函数、过程、触发器、枚举、域、序列和扩展
- 每个差异都会并排显示两个定义以及迁移它的 SQL。DBJoy 会按可运行的顺序编写整个迁移:类型先于使用它们的表,删除先于创建,外键在它们引用的表之后,视图在需要它的列更改前后被删除并重新创建
- 选择要包含哪些更改。删除数据的更改(删除表或列)默认不勾选并以红色标记;可能在现有行上失败的更改(添加 NOT NULL、唯一索引、类型更改)会被标记出来
- 复制脚本,将其保存为
.sql文件,在目标上的查询标签页中打开它,或在那里在一个事务中运行它(如果某条语句失败则不会有任何更改),并带有指明环境的确认 - 不比较:分区、授权、策略以及物化视图上的索引
导出
- CSV 或 JSON(每个表一个文件),或 SQL
INSERT(一个文件,按外键排序,序列重置) - 通过
pg_dump进行完整可恢复备份(随应用捆绑) - 行从单个一致快照流式传输,因此大表不会加载到内存中
外观
- 浅色和深色主题;默认跟随系统,或在 View → Appearance 或设置(⌘,)中选择一个
从 Claude Code 使用 DBJoy
当你使用 Claude Code 处理项目时,它可以通过 DBJoy 查询该项目的数据库。在终端中问“我们有多少所学校?”,Claude Code 会在 DBJoy 中找到连接,检查表并自行运行查询。你无需将凭据复制到项目中:DBJoy 使用你钥匙串中的密码和你设置的任何 SSH 隧道进行连接,并且共享连接是只读的。
设置
- 在 DBJoy 中,打开 Settings → MCP 并开启 Let MCP clients read your databases。
- 在 Shared connections 下,打开 Claude Code 可以使用的连接(或在某个连接的 Safety 部分使用 Share with MCP clients)。每个连接一开始都是未共享的,客户端之间也永远看不到彼此。
- Click Copy Command and run it once in Terminal. It registers DBJoy for all your projects:
claude mcp add --transport http --scope user dbjoy http://127.0.0.1:47821/mcp \ --header "Authorization: Bearer <token>" - In each project's
CLAUDE.md, say which connection it uses:The database is the DBJoy connection "Andromeda (dev)".
然后在该项目中直接提问:“这个月有多少学校注册了?”、“哪些表引用了 students?”。
在 Claude Code 中运行 /mcp 来检查 DBJoy 是否已连接。
Claude Code 能做什么
| 工具 | 作用 |
|---|---|
list_connections |
列出共享连接及其环境和数据库 |
list_tables |
列出某个 schema 的表、视图和例程,以及其他 schema |
describe_table |
显示列、键、索引、约束和外键 |
run_query |
运行 SELECT、WITH、EXPLAIN、SHOW 或 VALUES,并返回前 100 行 |
安全
- 只读。除读取之外的语句都会被拒绝,每个查询都在只读事务中运行,这也会阻止隐藏在 CTE 或函数中的写入。查询在 30 秒后超时。
- 仅限本地。服务器监听 127.0.0.1,因此你网络上的其他设备无法访问它。每个请求都需要令牌,来自其他站点网页的请求会被拒绝。
- 你能看到运行了什么。Settings → MCP → Recent activity 会列出每个请求:客户端、连接和 SQL。
- 可撤销。关闭某个连接即可将其隐藏,或点击 Reset Token… 断开所有客户端。
须知
- DBJoy 必须处于打开状态。该连接不需要打开窗口。
- 连接必须在 DBJoy 中保存其密码,因为 DBJoy 无法代表客户端索要密码。
- 如果端口 47821 被占用,请在 Settings → MCP 中更改它,然后重新复制命令。
- 其他 MCP 客户端(例如 Cursor)的工作方式相同。将它们指向
http://127.0.0.1:47821/mcp(Streamable HTTP),并带上请求头Authorization: Bearer <token>;Copy Token 会复制令牌。
键盘快捷键
| 操作 | 按键 |
|---|---|
| 新建查询标签页 | ⌘T |
| 关闭标签页 | ⌘W |
| 打开任意内容 | ⌘P |
| 运行语句 / 选区 | ⌘↩ |
| 运行全部 | ⇧⌘↩ |
| 取消查询 | ⌘. |
| 提交更改 / 保存查询 | ⌘S |
| 刷新 | ⌘R |
| 搜索行 / 在编辑器中查找 | ⌘F |
| ER 图 | ⇧⌘E |
| 比较 schema | ⇧⌘D |
| 导出表 | ⌥⌘E |
| 打开 SQL 文件 / 运行 SQL 文件 | ⌘O / ⇧⌘O |
| AI 助手 | ⌘J |
| 下一个 / 上一个标签页 | ⇧⌘] / ⇧⌘[ |
| 补全 | 输入、Esc 或 ⌃Space |
| 编辑单元格 | 双击或 Return;Tab 移动到下一个单元格 |
| 删除行 | ⌫ |
| 设置 | ⌘, |
开发
要求
- macOS 15+、Xcode 16+(Swift 6)
- libpq:
brew install libpq(keg-only;该包链接/opt/homebrew/opt/libpq,可用LIBPQ_PREFIX覆盖)
构建并运行
swift run DBJoy # run from the command line scripts/build-app.sh # build build/DBJoy.app (release) open build/DBJoy.app
或者在 Xcode 中打开 Package.swift 并运行 DBJoy scheme。
build-app.sh 会使用你钥匙串中的第一个 Developer ID / Apple Development 身份进行签名(可用
DBJOY_SIGN_IDENTITY 覆盖)。稳定的签名可避免每次重新构建后钥匙串都要求你输入密码。
DBJOY_SANDBOX=1 scripts/build-app.sh 会构建 Mac App Store 所需的沙盒变体。
设置 DBJOY_DATA_DIR=<folder> 可将连接、已保存查询和历史记录保存在另一个文件夹(演示、截图)中,而不是 ~/Library/Application Support/DBJoy。
示例数据库
docker run -d --name dbjoy-pg -e POSTGRES_PASSWORD=secret -p 55432:5432 postgres:17
psql "postgres://postgres:secret@localhost:55432/postgres" -f scripts/sample-db.sql然后添加一个连接到 localhost:55432,用户 postgres,密码 secret,数据库 dbjoy_sample。
示例包含 type_showcase,这是一个每个常见 Postgres 类型(enum、CHECK 列表、domain、数组、范围、JSON、网络类型、生成列……)各有一列的表,用于测试编辑器。只需用
scripts/type-showcase.sql 重新加载该表。
测试
swift test # unit tests (lexer, splitter, completion, SQL generation) DBJOY_TEST_PG=1 swift test # + integration and export tests against the sample database scripts/ssh-test-server.sh # throwaway sshd on 127.0.0.1:52222 next to the sample database DBJOY_TEST_SSH=1 DBJOY_TEST_SSH_KEY=/tmp/dbjoy_test_key swift test --filter SSHTunnelTests docker rm -f dbjoy-ssh
架构
Sources/
CLibPQ/ system module for libpq
DBCore/ engine-agnostic: models, DatabaseDriver/DatabaseConnection protocols,
SQLDialect (edit + DDL generation), SQL lexer/splitter, completion, export encoders
PostgresDriver/ libpq wrapper (serial queue per connection, single-row streaming,
cancellation, notices) + Postgres introspection and dialect
DBJoy/ SwiftUI app; AppKit for the data grid (NSTableView) and SQL editor (NSTextView)
MCP/ local MCP server (Streamable HTTP on 127.0.0.1) for Claude Code and other clients
Compare/ schema compare window (the diff and migration SQL live in PostgresDriver)
要添加引擎,请在新 target 中实现 DatabaseDriver、DatabaseConnection 和 SQLDialect,添加一个
DatabaseKind case,并在 Sources/DBJoy/Services/Drivers.swift 中注册它。
许可证
MIT。参见 LICENSE。
来源:Hacker News · github.com
