Planche 使用文档

结合应用中实际看到的界面介绍 Planche 的功能。所有截图都使用示例数据库,你可以直接在浏览器中打开它。

开始使用

Planche 是一个在浏览器中使用的数据库客户端。SQLite 文件可直接在页面中打开;MySQL、PostgreSQL 等网络数据库则通过你电脑上运行的代理连接。两种方式可以同时使用。

SQLite 文件:无需安装

把 .sqlite、.db 或 .sqlite3 文件拖到页面上,或从欢迎界面选择。编译为 WebAssembly 的 SQLite 会在页面内加载它,文件永远不会被上传。如果浏览器支持 File System Access API,修改可以写回原文件,否则会下载一份副本。

MySQL、PostgreSQL、SQL Server、Oracle、Neon、Supabase、Cloudflare D1:一条命令

浏览器本身无法与数据库建立 TCP 连接,因此需要由本地代理代为连接:

npx planche

代理会在 127.0.0.1:8888 启动,并显示配对链接,点击即可打开应用(加上 --open 会自动在浏览器中打开)。链接包含一次性代码,应用用它换取代理令牌,因此令牌本身不会出现在 URL 或 shell 历史中。之后浏览器只与 127.0.0.1 通信,代理再连接数据库;主机、用户名和密码都留在本机。

欢迎界面:接受条款,运行代理,或直接试用示例数据库。
欢迎界面:接受条款,运行代理,或直接试用示例数据库。

代理需要 Node.js 22 或更高版本。npx 会从 npm 仓库获取并运行它。npx planche@latest 运行最新版本;如需指定版本,请用版本号替换 latest。

用安装代替 npx

机器上没有 Node.js,或者你更想要一个常驻的命令?一行即可安装:

macOS, Linux

curl -fsSL https://planche.dev/install.sh | sh

Windows

irm https://planche.dev/install.ps1 | iex

所有文件都放在你的主目录下,全程不需要管理员权限。如果机器上已有 Node.js 22 或更高版本就直接使用,否则会下载一份官方运行时的私有副本,并用 nodejs.org 一同发布的校验和进行验证。之后 planche 就是 PATH 上的一个命令,无需访问仓库即可立即启动。安装结束后脚本还会直接把代理跑起来,所以第一次运行不需要再做任何事 —— shell 只有在新终端里才会读到新的 PATH。

用 planche upgrade 更新,用 planche uninstall 卸载;两种情况下 ~/.planche 里的设置都会保留。有新版本时代理最多每天提醒一次,可用 PLANCHE_NO_UPDATE_CHECK=1 关闭。安装脚本是纯文本,你可以先读再运行:curl -fsSL https://planche.dev/install.sh -o install.sh。

如果无法连接 planche.dev(例如没有网络或网络策略拦截),代理会在启动时检测到这一情况,并在自己的地址上提供随包附带的应用副本。除示例数据库不包含在该副本中外,其余功能相同。此时应用版本与代理版本一致;运行 npx planche@latest 可将两者更新到最新版本。

受限网络与内网 / 隔离网

唯一需要外部网络的只有把代理装进来这一步:npx 要从 npm 仓库下载。如果这条路被封,可以在能访问 npm 的机器上装一次再带进来(npm i -g planche),或用 npm pack planche 打成 tarball 拷贝进来,或发布到内部仓库。

之后就不再有出网的通信。代理在自己的地址上提供应用,而该页面完全不会向你机器之外发起任何请求——编辑器、SQLite 引擎和所有图标都在包里,没有 CDN、没有网络字体、没有统计。加上 --serve-app 可以跳过可达性检测,一开始就在本地提供;当网络不是拒绝请求而是直接吞掉时(例如强制门户会对任何地址作出响应),也应该用这个选项。

你放弃的只是真正需要互联网的东西:托管服务(Neon、Supabase、Cloudflare D1)、通往无法到达主机的 SSH,以及示例数据库。网络内部的数据库——包括供整个团队使用的网关——和其他环境下完全一样。

工作区

一个浏览器标签页中可以同时打开多个数据库连接。每个连接都有工具栏下方的独立标签,点击即可切换。

打开示例数据库后的界面:上方是连接标签,左侧是模式树,中间是 SQL 编辑器,下方是结果。
打开示例数据库后的界面:上方是连接标签,左侧是模式树,中间是 SQL 编辑器,下方是结果。

每个连接都会保存自己的工作区状态。切换到其他连接后再返回,之前打开的查询标签页、正在编写的 SQL 和查询结果都会保留。

  • 模式树(左侧)——这个连接的数据库、表、视图、存储过程等对象。单击展开,右键弹出该对象可用的操作。
  • 查询标签页(右上)——一个标签就是一个 SQL 编辑器,想开多少都行。用“Open Table”打开的标签页不显示编辑器,而是用网格显示该表的行。
  • 结果面板(下方)——Message 记录每条语句做了什么(影响行数、错误、耗时),旁边是 Info 和 History;每返回一个结果集就多出一个 Result 标签页。
  • 底栏——当前连接的名称、只读或事务未提交时出现的标记,以及最近一条状态消息。

关掉浏览器不会丢失工作:重新打开后连接会自动重连,查询标签页和其中的 SQL 会回来,从文件打开的 SQLite 数据库即使在你重新授予文件权限之前,也能从本地副本恢复。

连接数据库

在 Connection › Connect(Alt + N)中打开连接管理器,点击 Add New 后选择 DBMS。表单只显示该引擎需要的字段。Test Connection 用于验证设置;Connect 会打开连接标签页。

一个 MySQL 配置。左侧是已保存的配置,右侧表单随引擎变化。
一个 MySQL 配置。左侧是已保存的配置,右侧表单随引擎变化。

各引擎需要填什么

  • MySQL / MariaDB——主机、端口(3306)、用户、密码。数据库可选,树中会列出全部。字符集默认 utf8mb4。
  • PostgreSQL——主机、端口(5432)、用户、密码,以及必填的数据库:PostgreSQL 会话无法切换数据库。其中的模式会在树里充当“数据库”,Planche 用 SET search_path 切换。
  • SQL Server——主机、端口(1433)、登录名、密码、数据库。模式(dbo 等)充当“数据库”。Azure SQL 请开启 TLS;若是自签名证书,则不要勾选验证服务器证书。
  • Oracle——主机、端口(1521)、用户、密码,以及服务名(例如 FREEPDB1)。代理使用纯 JavaScript 的 thin 驱动,无需安装 Instant Client。模式即用户,通过 ALTER SESSION SET CURRENT_SCHEMA 切换。
  • SQLite——选择打开方式。在浏览器中无需安装任何东西,操作的是文件的内存副本。通过代理则由运行代理的机器上真正的 SQLite 打开文件,因此锁和 WAL 都正常工作,可与其他程序共用;这时需要填写路径,也可以让 Planche 在文件不存在时创建它。
  • Neon / Supabase——粘贴控制台里的连接字符串,主机、用户、密码和数据库会自动填好。TLS 始终开启,也没有 SSH 步骤。Supabase 请使用会话池(端口 5432)或直连;端口 6543 是事务池,每条语句可能落在不同后端,导致模式切换、临时表和手动事务失效,选中时 Planche 会给出提示。
  • Cloudflare D1——账户 ID、数据库 ID,以及具备 D1 Edit 权限(只读用 D1 Read)的 API 令牌。代理用它调用 Cloudflare REST API,没有 TCP 连接也没有 SSH。每个请求都会自动提交,因此 D1 禁用手动事务。
  • Redis——主机、端口(6379)、密码,服务器配置了 ACL 用户时还需填写用户(使用 default 用户时留空)。数据库字段是开始时所在的逻辑数据库(db0)。TLS 和 SSH 的用法与 SQL 引擎相同。
  • Elasticsearch / OpenSearch——主机和端口(9200)。填写用户和密码时,Planche 使用 Basic 认证登录;用户留空时,密码会作为 API 密钥(编码后的 id:key)发送。使用 https 时请开启 TLS;若是自签名证书(Elasticsearch 8 默认使用),则不要勾选验证服务器证书。
  • Cloudflare DO (wrangler dev)——只需 wrangler dev 服务器 URL(默认 http://localhost:8787),无需账户 ID、令牌或密码。它只读取本地 wrangler dev 会话,不支持已部署的 Durable Objects;每个对象显示为独立数据库。

密码、令牌与防护

  • Save password——不勾选时密码只存在到你关闭标签页;勾选后会随配置保存在本浏览器中。无论哪种方式,它都只会发给你自己的代理。
  • Agent token——留空表示使用配对链接得到的令牌。只有当你运行多个代理或手动配对时才需要填写。
  • 只读、环境配色和事务模式都是按配置设置的,参见安全。

SSH 隧道

只能通过跳板机访问的数据库需要使用 SSH 隧道。在配置中启用 SSH tunnel 并填写跳板机信息,本地代理会打开隧道并通过它连接数据库。

SSH 部分:跳板机、用户和认证方式。上方的主机与端口是从跳板机看到的数据库地址。
SSH 部分:跳板机、用户和认证方式。上方的主机与端口是从跳板机看到的数据库地址。

各字段

  • SSH Host / Port——跳板机。可以直接使用 ~/.ssh/config 中的 Host 别名:Planche 会像 ssh 命令那样解析它,自动补上 HostName、User、Port 和 IdentityFile(也会跟随 Include;不支持 ProxyJump)。
  • SSH User——留空则使用配置块里的用户。
  • SSH Auth——私钥、密码或 ssh-agent。
    • 私钥:选择密钥文件,或留空以使用配置中的 IdentityFile,再不然使用 ~/.ssh/id_*。密钥有口令时请填写 passphrase。
    • ssh-agent:使用运行 npx planche 那台机器的代理套接字(SSH_AUTH_SOCK),因此硬件密钥和转发的 agent 都能正常工作。
  • 上方表单里数据库的主机和端口是在跳板机上解析的,通常是 127.0.0.1 或内网名称。

主机密钥

第一次连接陌生的跳板机时会显示指纹并询问你是否接受。接受的密钥会追加到 ~/.planche/known_hosts,同时也会读取你已有的 ~/.ssh/known_hosts。如果之后密钥变了,连接会被拒绝而不是再次信任——和 ssh 命令的规则一致。

值得了解

  • 密钥和 passphrase 遵循 Save password 设置,并且只会从浏览器传给你本机的代理。
  • 隧道会随连接一起关闭。
  • SSH 认证失败会与数据库错误分开报告,让你知道该修哪一边。
  • 如果你希望代理完全忽略 ~/.ssh/config 和默认密钥,请在启动前设置 PLANCHE_SSH_CONFIG=none。

连接 wrangler dev 中的 Cloudflare Durable Objects

Cloudflare DO (wrangler dev) 仅用于本地开发。它读取你自己电脑上正在运行的 wrangler dev 会话中的 Durable Objects。不支持已部署的 Durable Objects。

为什么每个对象都显示为数据库

每个 Durable Object 都拥有自己的私有 SQLite 数据库,因此在架构树中,每个对象都显示为一个独立数据库。有名称的对象显示为 <namespaceId>/<object>。例如,do-probe-Counter/probe-one 表示 do-probe-Counter 命名空间中的 probe-one 对象,其中命名空间 ID 为 <script>-<ClassName>。这不是通常意义上的数据库名,而是传给 idFromName() 的对象名。用 newUniqueId() 创建的对象没有名称,会以其 64 位十六进制 ID 显示。

wrangler 维护一个开发注册表。同时运行的其他 wrangler dev 会话中的 Durable Objects 也会显示,所以一个 Planche 配置可以检查多个本地项目。

连接

  1. 在 Worker 项目中运行 wrangler dev。
  2. 运行 npx planche,然后创建 Cloudflare DO (wrangler dev) 连接。
  3. 输入 wrangler dev 服务器 URL,默认值为 http://localhost:8787。无需账户 ID、API 令牌、密码或 SSH 设置。

本地代理读取 <devUrl>/cdn-cgi/local/explorer/api 上的 wrangler Local Explorer API,因此无需在 Worker 端安装或部署组件。URL 必须是环回地址,否则代理会成为通向任意主机的 HTTP 代理。

没有服务监听时:Cannot reach a wrangler dev server at http://localhost:8787 (fetch failed). Run `wrangler dev` in your Worker project and try again.

端口属于其他服务器时:... answered (HTTP 401) but is not a wrangler dev server. Check the port, and that `wrangler dev` (wrangler 4.x) is what is running there.

SQLite 工具和存储

Durable Object 存储是 SQLite,因此 SQL 编辑器和 ctx.storage.sql 表与其他 SQLite 数据库一样工作。Planche 通过 sqlite_master 和 PRAGMA 读取表、视图、触发器、列和索引,支持 CREATE TABLE DDL、根据外键生成 ERD,并把单表 SELECT 结果匹配到原表,以便在网格中编辑行。

Planche 在树中隐藏 miniflare 的内部管理表 __miniflare_do_name。它不会隐藏 _cf_KV,因为其中存放由 ctx.storage.put() 写入的数据,值得查看。

每个请求都会自动提交。BEGIN、COMMIT 和 ROLLBACK 会被拒绝并显示说明,手动事务选项也会像 Cloudflare D1 配置一样隐藏。

为什么不支持已部署对象

Cloudflare 公共 API 只记录了两个 Durable Objects 方法:列出命名空间和列出对象。它没有提供已文档化的 SQL 端点来查询对象存储。

Cloudflare 控制面板有一个查询已部署对象的 Data Studio 标签页(Beta),其背后的端点可用 API 令牌访问。但该端点不在公共 API 参考中,可能随时更改。也没有 Durable Objects 专用的令牌权限。D1 有 D1 Read/D1 Edit,Workers KV 和 R2 也有各自的权限;但能解锁此端点的唯一权限是 Workers Scripts Edit。它赋予部署和修改账户中每个 Worker 的写权限。Planche 不会为了浏览数据而要求用户授予该权限。

目前如需访问已部署对象,请使用控制面板的 Data Studio,或从 Worker 暴露你自己的端点。

Redis

Redis 配置支持 Redis 6 和 7,以及使用相同协议的服务器(Valkey、KeyDB、Dragonfly)。代理为每个配置保持一个连接;打开 Pub/Sub 或 Monitor 标签页期间再多占用一个连接。

键树

树中列出逻辑数据库(默认 db0 到 db15)及其键数量。展开数据库后,键按第一个 : 段分组(user:、session:),每个分组也以同样方式展开。每一层都用 SCAN 每页读取 1,000 个键,达到 10,000 个时停止并给出提示;Planche 从不执行 KEYS,因为它遍历整个键空间期间会一直阻塞服务器。键名不会在会话之间保存。

键查看器

双击键会在单独的标签页中打开。标题栏显示类型、生存时间、长度和内存(MEMORY USAGE);可以在这里修改生存时间和键名,确认后也可删除该键。重命名使用 RENAMENX,因此不会覆盖已存在的键。

  • 哈希、集合、有序集合——用 HSCAN / SSCAN / ZSCAN 读取为表格,带有过滤框(普通文本,或 a* 这样的 glob)和加载更多。值和分数可直接编辑;行可以在表格中添加和删除。
  • 列表——索引和值,每次读取 200 个;元素可以编辑、推入任一端或删除。Redis 只能按值删除列表元素,因此删除时先用唯一标记覆盖该元素,再删除这个标记:共两条命令,如果其他写入者在两者之间移动了列表,索引可能会变。
  • 流——最新条目在前,显示其字段;可以添加(field value; field value)和删除条目。
  • 字符串和 RedisJSON——JSON 值显示为可折叠的树,HTML 值显示为渲染后的页面;切换到文本即可编辑。超过 1 MB 的值先加载前 1 MB,需要时再加载其余部分。HTML 在沙箱框架中渲染,不运行脚本,也不从其他主机加载任何内容。

控制台

Redis 连接上的查询标签页是一个控制台:每行一条命令,使用 redis-cli 语法(双引号支持 \n, \xHH 转义;单引号按字面处理),支持 # 和 // 注释。Ctrl / ⌘ + Enter 执行光标所在行的命令;整个脚本会逐条依次执行。SELECT n 会把标签页切换到该数据库。单个对象的响应显示为 JSON,记录显示为表格,结果上方的表格 / JSON 开关可以切换视图。

控制台会拒绝 SUBSCRIBE、PSUBSCRIBE 和 MONITOR:它们会一直占用连接,使树和所有其他标签页停止工作。请改用发布/订阅和监视工具。

工具

在树的空白处右键,或使用工具菜单:

  • 服务器信息——INFO 以卡片显示(版本、内存、命中率、每秒操作数、持久化、复制),以及每个数据库的键数量和可过滤的全部字段;可按需每 5 秒刷新一次。
  • 慢日志——SLOWLOG GET 最新的 128 条记录,显示耗时、客户端以及记录门槛;清空前会先询问。
  • 客户端——CLIENT LIST;确认后可以断开其他客户端。应用自身的连接会被标记,不能在这里断开。
  • 发布/订阅——订阅频道和 glob 模式(news orders.*)并实时查看收到的消息;向频道发布消息并查看有多少订阅者收到。
  • 监视——实时显示每个客户端执行的每条命令。Redis 会把每条命令复制给每个监视者,因此在繁忙的服务器上会降低吞吐量:请只短时间运行。当事件速度超过代理每 100 ms 500 个事件的上限时,会显示被跳过的命令数。
  • 内存分析——扫描一个数据库(最多 10,000、100,000 或 1,000,000 个键),分批查询每个键的大小、类型和过期时间:按类型、前缀和过期时间统计内存,并列出最大的 50 个键。20,000 个键约需 1 秒。MEMORY USAGE 对大型集合根据元素样本进行估算。点击键可打开它,点击前缀可删除其下的键。
  • 按模式删除键——找出匹配某个模式的键(每次最多 100,000 个),显示数量和其中 20 个,要求重新输入模式,然后用 UNLINK 每次 500 个删除。历史中只为这次操作记录一条。数据库节点和前缀节点的菜单中也有此项。

安全

只读配置只接受 Planche 读取命令列表中的命令;网关代理会根据服务器自身的 COMMAND INFO 标志检查每条命令。FLUSHDB、FLUSHALL、SWAPDB、SHUTDOWN 等命令执行前会先询问。AUTH、HELLO … AUTH、MIGRATE … AUTH、CONFIG SET requirepass 和 ACL SETUSER 中的密码在历史中会被遮盖。

暂不支持

Redis Cluster 和 Sentinel。连接到集群节点时,Planche 只显示该节点在 db0 中的键;对于由其他节点持有的键,会给出该节点,而不会跟随重定向。

模式树

模式树会随引擎变化:MySQL 和 SQLite 使用数据库 › 对象,PostgreSQL 和 SQL Server 另有模式层级。文件夹的计数可在展开前显示表的数量。

示例数据库的表、视图和触发器及其数量。
示例数据库的表、视图和触发器及其数量。

右键点击任意节点,都会出现适合那里的操作:

  • Open Table——按设置中的行数限制打开数据网格。
  • Generate SQL——根据真实的列和主键生成 SELECT、INSERT、UPDATE 或 DELETE 骨架,插入到光标处。
  • Show Create / Alter——对象的 DDL,或表设计器。
  • Copy Table to… / 比较 / 比较数据——见下文各节。
  • Truncate / Drop——单独放在菜单底部,且都需要重新输入对象名称。

SQL 编辑器

编辑器使用 VS Code 背后的 Monaco,并随应用一起打包。补全同时提供当前方言的关键字、函数,以及已连接数据库的表和列。

来自真实模式的补全,以及方言关键字。
来自真实模式的补全,以及方言关键字。

执行语句

  • Ctrl / ⌘ + Enter 运行选中内容,或光标所在的那条语句。
  • F9 遵循 设置 › 安全 › 执行范围(默认是整个脚本)。
  • Ctrl / ⌘ + Shift + Enter 始终运行整个脚本。

脚本由真正的解析器切分,而不是按分号:BEGIN … END 的主体不会被破坏,客户端 DELIMITER 命令、PostgreSQL 的 $$ 美元引用、SQL Server 的 GO 批处理,以及以 / 结束的 Oracle PL/SQL 块都能被理解。正因为每条语句都被分类,行数上限、破坏性确认和试运行才成为可能。

行数上限

没有限制的 SELECT 会被加上 LIMIT(视引擎而定为 TOP 或 FETCH FIRST),这样在大表上误发 SELECT * 也不会淹没浏览器。默认 500 行,生效时结果中会注明。已经自带限制的语句不会被改动。

历史与本地快照

每次执行都会记录耗时、行数以及运行所在的连接。
每次执行都会记录耗时、行数以及运行所在的连接。

History 标签页列出你运行过的语句;Query › Local History 保存每个编辑器标签页文本的快照,因此被替换或执行过的文本可以找回。任何内容存储前都会先掩盖密码字面量,你也可以在设置中完全关闭持久化。

结果网格

网格只渲染可见区域,因此数十万个单元格也能流畅滚动。若结果的所有列来自同一张带主键的表,便可直接编辑。

从树中打开的表:编辑工具栏、搜索、排序和列选择器。
从树中打开的表:编辑工具栏、搜索、排序和列选择器。

编辑

双击单元格编辑(也可以在刚点过的单元格上按 F2 / Enter),用 Add row 或 Add with form 插入,选中行来删除。在你按下 Commit 之前什么都不会执行,而且默认会先展示生成的 UPDATE、INSERT、DELETE 语句。Discard 会丢弃待提交的修改。

选择与复制

界面文字无法用拖动来选中,所以在网格上滑动鼠标不会把标签选成一片高亮。行是用点击来选的:点一行,再按 Shift 点另一行就选中两者之间的全部,按 ⌘ / Ctrl 点击则把某一行加入或移出选择。之后在单元格右键菜单里选的操作,会作用于所有选中的行。

单元格菜单作用于选择范围:链接、按值筛选、复制、编辑和列显示。
单元格菜单作用于选择范围:链接、按值筛选、复制、编辑和列显示。
  • 筛选:列 = 此值——以精确匹配重新加载该表。
  • 复制——单元格值、列名,或把选中的行复制为 TSV(含表头)、CSV、JSON 或可直接运行的 INSERT 语句。
  • 编辑 / 设为 NULL / 设为空字符串 / 删除行——都在提交前保持挂起。
  • 发送到草稿板——见下文。
  • 隐藏列——用工具栏的列选择器可以恢复。

自上次加载以来的变化

刷新表标签页时,会按主键把新数据与上一次加载做比较。变化的单元格会高亮(悬停可看之前的值),新行被标出,消失的行数以徽章显示——在部署或批处理之后特别有用。比较结果只存在于该标签页中,点 × 即可清除。

草稿板

草稿板是一个运行在你浏览器里的 SQLite 数据库。任何网格都能通过单元格右键菜单把行复制进去——一行、选中的行,或已加载的全部行。

从服务器表发送来的行会变成草稿板中的表,可以随意查询。
从服务器表发送来的行会变成草稿板中的表,可以随意查询。

列类型根据源类型推断,新建的表会立刻出现在草稿板的模式树中。因为它就是一个普通的浏览器 SQLite 连接,你可以像对待其他数据库一样查询和编辑,并用 Connection › Save Database File 导出为 .db 文件。它会被本地缓存,刷新后依然存在。草稿板中的内容不会被发送到任何地方。

随时用 Tools › 草稿板 打开或切换过去。

跨连接查询

在草稿板的查询标签页中,你可以用三段式名称 "连接名".数据库.表 引用任意已打开连接的表,并与其他内容联接:

SELECT o.id, o.total, u.email
FROM "Shop MySQL".shop.orders o
JOIN "User service".public.users u ON u.id = o.user_id
WHERE o.status = 'paid';

语句执行前,每个被引用的表都会被拉取成本地副本,SQL 也会被改写为使用副本,因此联接由浏览器中的 SQLite 完成。这样,MySQL 的表和 PostgreSQL 的表无需任何服务端配置就能联接。

把远程表拉进草稿板并在本地聚合的结果。
把远程表拉进草稿板并在本地聚合的结果。

副本每次运行都会刷新,每张表上限 10 万行,进度显示在底栏。Tools › 联合查询会打开一个预填了语法和当前连接名称的标签页。

比较与复制

这三个工具都不会自己执行任何东西——它们只生成脚本,供你阅读、修改并自行运行。

比较结构

两个数据库并排:缺少的、不同的和多出来的对象。
两个数据库并排:缺少的、不同的和多出来的对象。

Database › 比较结构(或树节点上的“比较表…”)会在任意两个已打开连接之间比较表、列、索引、视图、存储过程、函数、触发器和事件。比较 CREATE 语句时会剔除噪音——DEFINER、SQL SECURITY、算法以及数据库限定符——因此只显示真正的差异。在编辑器中打开脚本会把目标方言的 ALTER / CREATE 语句交给你,除非勾选相应选项,所有 DROP 都是注释状态。

比较数据

以源表主键为键的行级比较。
以源表主键为键的行级比较。

Database › 比较数据按源表主键匹配行,并把值作为规范化文本比较,因此不同驱动返回日期、小数和 JSON 的方式不会造成假差异。你会看到目标缺少的行、不同的行(逐列展示)以及只有目标才有的行,还有一份 INSERT / UPDATE / DELETE 脚本——DELETE 默认注释掉。每侧最多加载 5 万行,并显示进度。

复制表到…

在另一个连接上重建表——只要结构,或连同数据。
在另一个连接上重建表——只要结构,或连同数据。

右键一张表并选择 Copy Table to…,即可在任意其他已打开的连接或数据库上重建它。CREATE TABLE 以目标方言生成并可编辑,因此调整一下类型就能把 MySQL 的表复制到 PostgreSQL。行会分批流式传输并显示进度条。如果同名表已存在,复制会中止——选择“删除并重建”则必须先重新输入表名。

AI 助手

右侧面板不是写好 SQL 让你复制,而是直接操作这个应用:读取结构、打开查询标签页、在那里执行,并在改动数据前征求你的确认。从右边缘的图标或 工具 › AI 助手 打开。

一个问题如何变成答案

面板读取结构、打开标签页并在那里执行查询。答案上方的卡片就是它调用的工具。
面板读取结构、打开标签页并在那里执行查询。答案上方的卡片就是它调用的工具。

用平常的话问就行。模型看不到你的屏幕,所以它会先问应用当前打开了什么,再读取要用的表的列。它调用的每个工具都会留下一张卡片,因此这条查询依据什么写成一目了然,而不是靠它自己声称。写好的语句会在查询标签页中打开并执行,于是你能看到进度、中途取消,结果也能像其他查询一样排序和导出。

它写的语句会先交给引擎做执行计划。引用了不存在的列时,错误会回到模型手里由它自己改正,坏掉的查询不会出现在你眼前;如果计划是对大表做全表扫描,执行前会先问你。

它不会做的事

写入会停在这里。卡片显示是哪条语句,预览在写入前数出会改动多少行。
写入会停在这里。卡片显示是哪条语句,预览在写入前数出会改动多少行。
ai-dry-run
  • 只用一个连接 —— 你当前打开的那个。没有参数可以指定别的连接,也没有打开或关闭连接的工具。用哪个数据库,由你在用哪个决定。
  • DROP 和 TRUNCATE 不会执行 —— 你批准也不行,换个说法不行,藏在分号后面也不行。它可以写进标签页并告诉你会毁掉什么,但执行是你的事。
  • 写入先问你 —— 之后还要走和你手打的语句一样的关卡:显示改动行数的试运行、破坏性语句确认、只读连接的拒绝。

模型从哪里来

设置 › AI。其中两种完全不需要密钥。
设置 › AI。其中两种完全不需要密钥。

在 设置 › AI 中选择。密钥交给本地代理并在那里使用,不会存在浏览器里,也不会发往 planche.dev;你的 SQL 和结构同样不会。

  • API 密钥 —— Anthropic、OpenAI 兼容端点或 Gemini。是否保存由你决定,保存前会先告诉你写到哪个文件。
  • 本机登录 —— 执行过 ant auth login 后 SDK 会自己找到凭据,无需粘贴任何东西。
  • 本地 CLI —— 已安装并登录的 Claude Code 或 Codex,完全不需要密钥。

让别的代理来操作 Planche

帮助 › 连接 AI 代理:令牌能触及的范围,以及要粘贴的那一行。
帮助 › 连接 AI 代理:令牌能触及的范围,以及要粘贴的那一行。

帮助 › 连接 AI 代理 会给你配置内容。只要支持 HTTP 版 MCP 即可,编辑器里的代理就能使用同样的工具。调用在浏览器标签页中执行,经过同样的关卡;写入会在那里请你确认,并标注为来自外部。给出的令牌只用于那一个端点,重启后依然有效;吊销它会断开你交出过它的所有程序。

安全

在生产库中执行不带 WHERE 的 DELETE 很容易造成意外影响。Planche 会在这类语句执行前提供多层确认;如有需要,也可在设置中逐项关闭。

试运行:改动之前先看看会影响哪些行

把 UPDATE 预览为 SELECT:会影响多少行,具体是哪些行。
把 UPDATE 预览为 SELECT:会影响多少行,具体是哪些行。

从编辑器执行 UPDATE 或 DELETE 前,Planche 会将它改写为读取受影响行的 SELECT,并显示行数和样本。它支持各方言的联接写法:MySQL 的 UPDATE a JOIN b、PostgreSQL 的 UPDATE … FROM 与 DELETE … USING、SQL Server 的 UPDATE 别名 … FROM,以及 Oracle 的相关子查询。无法可靠改写的语句将不显示预览,以免给出错误的结果。

其余的网

  • 破坏性语句确认——DROP、TRUNCATE 以及没有 WHERE 的 DELETE/UPDATE 都会先询问,并原样列出将要执行的语句。从树中删除表或数据库时还需要重新输入名称。
  • 只读连接——写入在到达数据库之前就会被拒绝。
  • 网格提交预览——写入前展示生成的语句。
  • 手动事务——在你确认之前不会提交。
  • 环境配色——生产环境看起来就和预发不同。
设置 › 安全——碍事的防护都可以关掉。
设置 › 安全——碍事的防护都可以关掉。

ERD

Tools › 查看 ERD 会根据所选数据库的外键绘制实体关系图,采用鸡爪符号,实体可拖动,列宽可调整。布局按数据库保存,所以你整理好的排布明天依然在。

示例数据库:23 张表及其外键。
示例数据库:23 张表及其外键。

你自己定义的列链接会显示为虚线关系。当链接指向图外的表(另一个数据库或另一个连接)时,会在源表旁添加一个幽灵实体,使关系依然可见。

表设计

Create Table 和 Alter Table 会打开一个设计器,包含三个标签页:列、索引,以及(对支持的引擎)存储属性。

列的类型、长度、默认值、是否可空以及主键。
列的类型、长度、默认值、是否可空以及主键。

SQL 标签页会用你所用引擎的方言展示 Planche 将要执行的语句,并随着输入实时更新——既适合学习方言,也便于确认自己接下来要做什么。

生成的 DDL 始终与表单保持同步。
生成的 DDL 始终与表单保持同步。

其余功能在 Table 和 Database 菜单里:重命名、复制结构、创建和删除数据库,以及在引擎支持时的用户管理、进程列表、服务器变量和状态。

导出

导出一张表:分隔符、表头,以及流式写出时的进度条。
导出一张表:分隔符、表头,以及流式写出时的进度条。
  • 下载为 CSV——当前结果,或整张表。表会按主键顺序分页读取,并在浏览器支持 File System Access API 时直接写入你选择的文件,因此再大的表也不必放进内存。过程中显示进度,也可以中途停止。
  • 模式导出为 HTML——一个自包含页面,包含你勾选的表的列和索引。
  • 导出 / 导入列链接——把虚拟外键存成 JSON 文件,便于换机器或分享给同事。
  • 复制为 INSERT——在网格中手动搬运少量行时使用。
  • 保存数据库文件——把浏览器 SQLite 数据库(包括草稿板)写回磁盘。

以 =、+、- 或 @ 开头的 CSV 值会加上一个撇号,让表格软件把它当作文本而不是公式。

网关模式(团队)

一个代理就能服务整个团队。在网关模式下,数据库凭据保存在共享主机上的配置文件里,浏览器只按名称选择配置。

Terminal

npx planche --gateway gateway.json --addr 0.0.0.0 --allow-remote \
  --token "$(openssl rand -base64 24)" --public-url https://sql.example.com

gateway.json

{
  "name": "Acme staging",
  "profiles": [
    {
      "name": "Shop (read-only)",
      "driver": "mysql",
      "host": "db.internal",
      "port": 3306,
      "user": "reporting",
      "password": "…",
      "database": "shop"
    },
    {
      "name": "Shop (writable)",
      "readOnly": false,
      "driver": "postgres",
      "host": "pg.internal",
      "port": 5432,
      "user": "app",
      "password": "…",
      "database": "shop"
    }
  ]
}
  • name——网关的名称,会显示在连接界面上。
  • profiles[].name——浏览器看到的名称,也是客户端唯一会回传给服务端的内容。
  • profiles[].readOnly——不写就是只读;要允许写入请设为 false。
  • 其余字段与连接表单里填的完全同名:driver(mysql、postgres、mssql、oracle、sqlite、d1)、host、port、user、password、database;此外 Oracle 用 serviceName,SQLite 用 file,Cloudflare D1 用 accountId、databaseId、apiToken。也可以照样写 ssh 配置块。

需要经跳板机的配置要加一个 ssh 块。此时上面的 host 和 port 是从跳板机看到的地址,因此通常写 127.0.0.1:

gateway.json(profiles 中的一项)

{
  "name": "Shop via bastion (read-only)",
  "driver": "mysql",
  "host": "127.0.0.1",
  "port": 3306,
  "user": "reporting",
  "password": "…",
  "database": "shop",
  "ssh": {
    "host": "bastion.example.com",
    "port": 22,
    "user": "deploy",
    "auth": "key"
  }
}
  • auth 可以是 key、agent 或 password。用 key 且不写 privateKey 时,代理会用网关主机 ~/.ssh/config 中为该主机指定的 IdentityFile,没有则退回 ~/.ssh/id_*——服务器上通常这么做,因为这样密钥不会留在配置文件里。agent 使用网关的 SSH_AUTH_SOCK;password 需要 password 字段。
  • 如果确实要写 privateKey,它的值是密钥内容(PEM / OpenSSH),不是路径。密钥有口令时再加 passphrase。
  • 跳板机的主机密钥必须先在网关机器上被信任。 在那台机器上执行一次 ssh bastion.example.com,或在配置的 acceptHostKey 里写上 SHA256:… 指纹来固定:网关模式下浏览器只发送配置名称,无法回答“未知主机密钥”的确认。
  • 配置默认只读,而且只读由代理强制执行:每个请求只接受一条 SELECT 形态的语句,并在引擎支持时把会话本身设为只读。浏览器端的防护只是便利功能,而这一层无法从客户端绕过。
  • 携带凭据而非配置名称的请求会被拒绝。
  • 代理自己提供 Web 应用,因此页面只与自身来源通信,严格的内容安全策略保持不变。
  • 它使用明文 HTTP:请在前面放一个 TLS 反向代理,并用 --public-url 告知公开地址。

同事打开该地址,在连接对话框的 Configure 处粘贴一次令牌即可;随后配置就会出现在欢迎界面和连接管理器中。

连接同步(端到端加密)

连接同步把你的连接配置保存在 planche.dev 上,换一台电脑也能直接用。所有内容在上传前就已在浏览器里加密,所用的密钥服务器永远拿不到。入口在 连接 › 连接同步。从 1.0 起这是 Pro 功能,0.x 的所有版本均免费。

开启同步

  1. 用 GitHub 登录。登录只是让服务器知道哪个保险库属于你。
  2. 设置一个至少 10 个字符的口令,输入两遍。口令特意与 GitHub 登录分开:服务器看得到你的登录信息,所以登录本身绝不能用来解锁你的数据。
  3. 连接配置随即加密并上传。在另一台电脑上用同一个账号登录,输入同一个口令即可解锁。

加密方式

  • 浏览器用 PBKDF2-SHA256(600,000 次迭代,随机 16 字节盐值)把口令派生为 256 位 AES-GCM 密钥。每次保存都使用新的 12 字节随机数(nonce)。
  • 密钥以不可导出的方式创建,只存在于当前标签页的内存中。密钥和口令都不会写入磁盘,也不会发送到任何地方,因此每次开启新会话都要重新输入口令。
  • 服务器为每个账号保存一个加密保险库。旁边以明文保存的只有重建密钥所需的参数(盐值和迭代次数)、nonce、版本号以及最后一次保存的时间,这些都不会透露任何内容。
  • 账号方面,服务器保存你的 GitHub id 和邮箱地址(邮箱设为私密时改存 GitHub 用户名),以及登录期间的会话。

保险库里有什么

  • 连接配置:主机、端口、用户、各项选项,以及你在这些配置上设置的列链接。
  • 密码、SSH 密码和私钥——但仅限开启了 保存密码 的配置。你不愿留在本机的密钥,同样不会留在服务器上。
  • 示例数据库和草稿库不在其中:哪台电脑需要,就在哪台电脑上创建。
  • 查询历史、查询结果和数据库中的数据一律不会同步。

多台电脑之间

每个配置都记录了最后修改时间,合并两个保险库时以较新的那份为准。删除操作会保留 90 天,所以在一台电脑上删掉的配置不会从另一台电脑上冒出来。如果两台电脑同时保存,服务器会拒绝后到的那次,那台电脑会先合并较新的保险库再重新保存,而不是直接覆盖。

忘记口令怎么办

服务器上的保险库任何人都无法解密,我们也不例外,因此无法找回。请在仍保留着连接配置的电脑上点击 从服务器删除,然后用新口令重新开启同步。删除账号 会删除保险库和你的登录信息;无论哪一项,都不会动你电脑上的连接配置。

同步只在 planche.dev 上可用。本地代理提供的应用副本不会访问互联网,因此那里没有同步功能。

隐私与安全

  • 你的数据不会到我们这里。 planche.dev 只提供静态页面;查询和结果只在你的浏览器与你自己的代理之间往返(浏览器 SQLite 则完全留在页面内)。
  • 凭据留在本地。 配置保存在浏览器存储中;除非你选择保存,密码和 SSH 机密只在会话期间保留。应用会拒绝与非回环地址的代理通信(除非该代理正是提供本页面的那个),因为远程代理意味着要把凭据发到网络上。
  • 代理会认证每个请求。 除健康检查外的所有路由都需要令牌,多次令牌错误会短暂锁定认证,只有应用来源可以调用它,绑定到非回环地址需要显式开关和令牌。
  • SQLite 文件访问受限。 代理只打开主目录(不含隐藏目录和系统目录)或你指定目录下的文件,并且在你启用之前拒绝 ATTACH。
  • 查询历史会脱敏。 在保存历史或快照之前会掩盖密码字面量,也可以关闭持久化。
  • 统计匿名且可选。 只统计类别性事实——用的是哪个引擎、哪个对话框、语句是否成功——绝不收集 SQL 文本、主机名、数据库、表或文件名。设置里一个开关即可关闭。

Planche 按现状提供。这里描述的安全措施是便利功能而非保证:你要为自己运行的每条语句负责,请保留备份。

键盘快捷键

编辑器快捷键在 SQL 编辑器获得焦点时生效,其余在任何位置都可用。

按键作用
F9执行——按照 设置 › 安全 › 执行范围,运行整个脚本或光标处的语句。
Ctrl / ⌘ + Enter运行选中的内容,或光标所在的那条语句。
Ctrl / ⌘ + Shift + Enter无论执行范围如何设置,都运行整个脚本。
Ctrl / ⌘ + K快速命令面板:输入即可跳转到表、菜单操作或连接。
Alt + N打开连接管理器。
Alt + T在当前连接上新建查询标签页。
Shift / ⌘ / Ctrl + click在结果网格中扩展(Shift)或切换(⌘ / Ctrl)行选择。
F2 / Enter在结果网格中编辑刚点过的单元格(与双击相同)。
Ctrl / ⌘ + F在编辑器中查找和替换。