所有数据库工具都默认键盘前坐着一个人。Quarry 默认操作者是 agent —— 给它一个带安全栏的查询内核,长出多张脸:CLI、GUI、agent skill、MCP。
$ qy exec shop --sql "select …" --format json ✓ exit 0 — auto LIMIT applied $ qy exec shop --sql "delete from orders" ✗ exit 8 — blocked without --write
DBeaver、TablePlus、pgAdmin —— 都是好工具,但都是为"人在点击"设计的。而越来越多的查询由 AI agent 在 skill、脚本、CI 里执行。agent 不会"自己小心",工具必须替它小心。
每次查询返回 {columns, rows, rowCount, truncated, elapsedMs, engine, sql} —— 稳定的结构化契约。不用爬屏幕,不用解析文字。
默认只读、自动行数上限、prod 分级确认。栏在内核,任何客户端 —— 无论人还是 agent —— 都找不到能绕过它的入口。
退出码就是 API:0 成功、2 连接错、3 SQL 错、8 安全拦截。agent 对结果直接分支,不用猜 stack trace。
我们没有往数据库 GUI 上钉一个聊天机器人。
你的 agent 本来就是 —— Quarry 给它一个通往数据的安全插座。
qy gui 在同一个内核上起一个本地零构建 web 工作台:分组连接树 + 环境切换器(prod 变红)、多标签 SQL 编辑器(补全)、一键 EXPLAIN、类型着色网格(键盘导航 + 可折叠 JSON 查看器)、可搜索历史 —— 亮暗双主题、中英双语,重启不丢状态。
连接管理、查询执行、schema 内省、安全栏都在一个可 import 的内核里,其余全是薄壳。修一次 bug,所有脸同时受益;加一道栏,没有任何脸能忘掉它。
连接 · 执行 · 内省 · 安全栏 · 结果契约
写/DDL 一律拦截,除非显式 --write;prod 连接在此之上还需再确认一次。每条查询自动注入 LIMIT 500,除非主动放开。环境默认 dev —— 最安全的那个。
一个 workspace 就是一个目录:connections.toml 加上带元信息头的 .sql 命名查询。它放在你的仓库里,git 管理,团队成员和 agent 共用。内核本身零密钥、零业务逻辑 —— 而且 Quarry 能把多个 workspace 聚合到同一个视图。
[shop_dev] url = "postgresql://…dev…/shop" db = "shop"; env = "dev" [shop_prod] url = "postgresql://…prod…/shop" db = "shop"; env = "prod" [internal_db] url = "postgresql://…@127.0.0.1/appdb" ssh_host = "bastion.example.com" # auto tunnel
-- @name: recent_orders -- @db: shop -- @desc: Latest orders with customer names -- @param: days (int, default=7) SELECT o.id, c.name, o.amount, o.status FROM orders o JOIN customers c ON c.id = o.customer_id WHERE o.created_at > now() - make_interval(days => :days) ORDER BY o.created_at DESC;
同一个逻辑库的 dev / staging / prod 折叠成一个 env-set —— 一份命名查询跑任意环境:qy run recent_orders --env prod。
纯 Python stdlib。引擎直接调用你机器上久经考验的客户端 —— 没有 Electron、没有守护进程、没有云、没有遥测。pipx 装上就能跑。
from quarry import run_query —— CLI、GUI、MCP server 用的同一个内核,三行代码进你自己的工具,同样的安全栏、同样的结果契约。
你的连接、查询和结果永远不离开你的机器。GUI 只绑定 localhost 且拒绝非本地来源。它没有任何"回传"的地方。