Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>PostgreSQL StudioNew to Visual Studio Code? Get it now.
PostgreSQL Studio

PostgreSQL Studio

lupee

|
2 installs
| (0) | Free
PostgreSQL 数据源浏览、表结构迁移与数据同步
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

PostgreSQL Studio

在 VS Code 侧边栏里浏览 PostgreSQL 数据源,查看和修改表数据、表结构,在命令窗口里执行 SQL,做表结构迁移和表数据同步。

侧边栏顶部三个页签:

页签 做什么
数据源 添加 / 编辑 / 测试 PostgreSQL 连接;按需展开 数据库 → 模式 → 表 / 视图 / 函数,表下分列 / 键 / 索引;查看数据、编辑结构、查看 DDL、添加和删除库 / 模式 / 表;每个模式一个 SQL 命令窗口
迁移 删除目标表,按源表一模一样地重建(结构、备注、索引),可选按主键迁移数据
同步 源表、目标表都已存在,按字段名称对应、按主键 upsert 数据,不改表结构

迁移、同步两页都是两层的树:文件夹 → 任务,可以单独执行一个任务,也可以按顺序执行整个文件夹。

所有配置保存在 ~/.x1/postgresql-studio/conf.yaml(见「配置文件」)。设置项、命令面板里的命令见「设置项与命令」。

数据源

添加 / 编辑数据源

「添加数据源」弹窗填写:名称、主机、端口、用户名、密码、默认数据库、SSL(disable / require / verify-full),可以先「测试连接」。默认值是 127.0.0.1 / 5432 / postgres / postgres;名称留空时取「主机:端口」。require 只加密不校验证书,verify-full 校验证书和主机名。连接超时 15 秒。

数据源右键:编辑实例、复制实例(名称加「副本」)、测试连接、添加数据库、删除实例。删除时会提示有几个迁移 / 同步任务引用了它,删完关掉它名下开着的数据查询页、编辑表、添加库 / 模式和命令窗口。编辑保存后旧连接作废,命令窗口的会话断开,树上这个数据源重新加载。

对象树

树的每一层都是展开时才查询。数据源 → 数据库 → 模式 → 「表 / 视图 / 函数」三组;表下面分「列 / 键 / 索引」三组:列是字段(主键带黄色钥匙图标,timestamp / timestamptz 字段图标为黄色,其余 NOT NULL 字段图标为蓝色,悬停看类型、默认值、备注),键是主键、唯一约束、外键,索引是表上全部索引(含主键、唯一约束背后的索引);视图下面直接列出字段。系统模式(pg_*、information_schema)、扩展自带的对象、分区表的分区、聚合和窗口函数不列出。

备注显示在名称后面:数据库的是黄色、模式的是紫色(和各自的图标同色),表、字段、键、索引的是绿色。表悬停显示估算行数(没统计过的不显示)和「分区表」,视图标出「物化视图」,函数标出「存储过程」或返回类型。

右键菜单和行尾按钮:

节点 右键菜单 行尾按钮
数据源 编辑实例、复制实例、测试连接、添加数据库、删除实例 刷新(鼠标移入时显示)
数据库 复制名称、添加模式、删除数据库 刷新(鼠标移入时显示)
模式 复制名称、添加表、删除模式 显示命令窗口、刷新
表 复制名称、查看数据、查看 DDL、编辑结构、以此为源表新建迁移任务 / 同步任务、删除表 显示命令窗口、刷新
视图、函数 显示命令窗口、查看定义、复制名称、刷新 查看定义、刷新
视图的字段 显示命令窗口、复制名称 —
表 / 视图 / 函数、列 / 键 / 索引这些分类节点,表下的字段、键、索引 — —

「复制名称」:表、视图、函数复制「模式.名称」,其余复制名称本身。分类节点没有菜单和按钮:别处新建了表、视图、函数,点模式行尾的刷新就能看到,分组后面的数量也跟着更新;也可以选中某个分组按 F5 只刷新这一组,刷出了对象的空分组会自动展开;表下的分组按 F5 刷新的是表。

键盘:↑↓ 移动,←→ 收展,Enter / 空格切换收展,任何节点上 F5 刷新。双击表打开数据查询页,双击视图 / 函数查看定义,双击字段 / 键 / 索引复制名称。空白处右键「添加数据源」。

工具栏:搜索框(筛选的是已加载的节点)、全部折叠、精简折叠(只收起表和视图下面的节点,上面几层保持展开)、全部刷新,以及「更多」菜单:打开配置文件、重新加载配置、清除失效偏好、显示日志。

查看 DDL 与定义

表的「查看 DDL」在编辑器里打开建表语句:字段、约束、备注、索引、外键,分区表带 PARTITION BY。视图、函数的「查看定义」打开 CREATE OR REPLACE VIEW … AS / CREATE MATERIALIZED VIEW / pg_get_functiondef 的输出。

数据查询页

打开与工具栏

双击表名(或右键「查看数据」)在编辑区打开数据查询页,同一张表只开一个页。以表格分页显示表内容,默认每页 10 行;表头显示类型,主键带钥匙图标,悬停看备注;值按数据库的文本输出原样显示,NULL 单独标出,换行显示成 ↵,单个值超过 2000 字符截断(悬停看开头)。

上方工具栏:SELECT 按钮(展开字段勾选列表,最上面是「全部」,勾选结果在执行查询时生效,按钮上显示 * 或「已选数/总数」,一个字段都不勾不能查询)、WHERE 按钮和 ORDER BY 按钮(见下面的「查询条件和排序」)、「查询」按钮(条件行、排序行里回车也执行),右边是「添加 / 删除 / 提交 / 撤销」(见「增删改记录」)。

底部状态栏:左边显示满足条件的总条数和这页的查询耗时(鼠标悬停显示数据源 / 库 / 表),右边是首页 / 上一页 / 下一页 / 末页、每页行数(10 / 20 / 50 / 100 / 500)和「导出」。先按填写的排序,再按主键排序(没填排序就只按主键),翻页稳定。

查询在只读事务里执行,条件或排序里夹带别的语句、调用写数据的函数都会被拒绝。每页最多等 30 秒,超时提示加条件缩小范围;总行数最多统计 5 秒,超时则只能逐页翻,不能直接跳到末页。

查询条件和排序

WHERE、ORDER BY 两个按钮上显示实际参与查询的子句,点开是多行列表,每行是一个勾选框加一个输入框(写 WHERE / ORDER BY 后面的部分,行首顺手写的关键字会去掉)。敲字段名时弹出字段联想(Ctrl+Space 也可呼出,↑↓ 选择、回车 / Tab 填入、Esc 关闭,含大写字母或关键字的字段名自动加双引号)。

勾选的行拼进子句:条件只有一行时原样使用,多行时各自加括号、用 AND 连接,例如 (id > 100) AND (status = 'paid' OR status = 'done');排序按从上到下的先后用逗号连接,例如 created_at DESC, id,行尾的上移 / 下移按钮或输入框里的 Alt+↑↓ 调整先后。没勾选的行留作草稿,不参与查询但会保存,勾上即可启用。列表顶部的「全部」一键勾选或取消所有行,底部「添加条件」/「添加排序」新增一行,行尾 × 删除一行;有草稿时按钮上显示「勾选数/行数」。行里回车执行查询并收起列表,没有联想时 ↑↓ 在行间移动,Esc 或点别处收起,收起时空行自动丢掉。

选中、复制与粘贴

点格子选中它,点行号选中整行,点列标题选中整列,点左上角的 # 全选;Ctrl / ⌘ 点加选(再点一次取消,macOS 上用 ⌘),Shift 点从起点连选成方块,按住鼠标拖动也能连选;方向键移动,Shift+方向键扩大选区,Ctrl / ⌘+A 全选。新加的行只能整行选中。选中后:

  • 直接敲字(包括中文输入法)或按回车 / F2,在起点格子打开编辑框,回车后写进所有选中的格子,编辑框后面标出格数;编辑框的「NULL」按钮同样作用于所有选中的格子;
  • 复制(Ctrl / ⌘+C):一格时复制原值;多格时复制成制表符分隔的文字,含制表符、换行、双引号的值加双引号(Excel 的写法),NULL 为空,可以直接粘进 Excel、DataGrip。在本工具的数据页之间复制粘贴时值原样保留,NULL 还是 NULL;
  • 粘贴(Ctrl / ⌘+V,跟 DataGrip 一样):剪贴板只有一个值时,写进每个选中的格子;是多行、多列的一块时,从选中区域的左上角开始往右、往下铺开,超出最后一列的丢掉,下面的行不够就自动添加新行,粘贴完选中粘贴进去的那一块。在新加的行的输入框里粘贴一块也从这一格铺开(一个值照常粘进输入框);空表点一下列标题再粘贴,从这一列开始添加新行;
  • 右键菜单:「复制」「粘贴」「设为 NULL」。

文本类型写空文字是空字符串,其余类型是 NULL;布尔认 t / yes / on / 1 等写法。不能改的格子(生成列、截断的值、标记删除的行等)和 NOT NULL 却要写 NULL 的格子会跳过,报错条里说明跳过了几格、为什么。

增删改记录

点「添加」在表格末尾加一行输入框,每个显示的字段一格,格子里的灰字说明留空时写进去的是什么(自动生成 / DEFAULT / NULL / 必填);留空的格子和没显示的字段都用默认值(没有默认值为 NULL),生成列不能填。布尔字段是下拉:有默认值时第一项是 DEFAULT,NOT NULL 又没有默认值时第一项是灰掉的「必填」,然后是 true / false / null(NOT NULL 字段的 null 灰掉不能选);日期、时间戳字段点格子弹出日历(时间戳还有时、分、秒,↑↓ 加减;底部「今天 / 现在」填入当前时间,「清空」清空),点日期即填入,也可以直接在格子里敲,带时区的时间戳按本机时区填(末尾带上如 +08:00 的偏移)。表格里的布尔值显示成 true / false。

双击已有记录的格子直接修改:格子换成编辑框(布尔是只有 true / false 的下拉,日期、时间戳直接弹出日历,有换行的值是多行框),回车(多行框里 Ctrl / ⌘+回车)或点别处记下,Esc 放弃,Tab / Shift+Tab 跳到这一行下一个 / 上一个能改的格子。每个字段(包括布尔)的编辑框后面都有「NULL」按钮,点了把格子设为 NULL:可以为 NULL 的字段按钮是蓝色,NOT NULL 的灰掉不能点;清空格子时,文本类型(text、varchar、char、name、citext)存空字符串,其余类型存 NULL。改过的格子标蓝,鼠标悬停显示原值,改回原值就不算改过。表没有主键、生成列、GENERATED ALWAYS 的标识列、超过 2000 字符被截断的值、标记删除的行不能改,双击时说明原因。带时区的时间戳在日历里按本机时间显示,选完写回的还是同一时刻。

选中格子所在的行就是选中的行,点「删除」或在表格里按 Delete 键:已有的行标成粉色,新加的行直接去掉;选中的都已标记时再删一次取消标记。点「提交」先检查必填的字段(NOT NULL 且没有默认值的标红),再在一个事务里先删、再改、后加:删除、修改按查询时的主键定位(没显示主键字段也行),修改只写改过的字段,每条必须正好删掉 / 改到一行,找不到(已被别人删除或改了主键)就报错;任何一条失败(外键、约束、类型不对、等锁超过 10 秒)整体回滚,报错里说明是第几条并在表格里标出那一行,修改都留着,改好可以再提交。提交成功后重查当前页(这页删空了就回上一页),状态栏显示新增、修改、删除了几行。「撤销」放弃所有没提交的修改。修改只在当前页上,有没提交的修改时不能执行查询、翻页、改每页行数;表没有主键时只能添加,不能修改、删除已有的行。

导出

点状态栏最右边的「导出」选格式,再选保存位置(默认文件名是 表名_insert.sql / 表名_update.sql / 表名.csv / 表名.tsv,记住上次的目录)。导出的是满足条件的全部行,不受每页行数限制;字段、条件、排序按上次执行的查询(列表里改了但没执行的不算),排序在最后再按主键排,顺序稳定。导出在只读事务里用游标分批读、边读边写文件,大表也不占多少内存;通知栏显示进度,可以取消,导出中按钮显示「导出中…」。先写到同目录的 .part 临时文件,成功后才改成选定的文件名,失败或取消不会留下半截文件,也不会覆盖原来的同名文件。完成后可以直接打开文件或所在文件夹。

  • SQL INSERT:每行一条 INSERT INTO "schema"."table" (字段…) VALUES (…);,只写显示的字段。生成列不写;写入 GENERATED ALWAYS 的 identity 字段时加 OVERRIDING SYSTEM VALUE。
  • SQL UPDATE:每行一条 UPDATE … SET … WHERE 主键 = …;,按主键定位,SET 显示的字段里主键、生成列、GENERATED ALWAYS identity 以外的。表没有主键时不能选。
  • CSV:逗号分隔、CRLF 换行,第一行是字段名;含逗号、双引号、换行的值加双引号,NULL 写成空,空字符串写成 ""。文件带 UTF-8 BOM,Excel 双击打开中文不乱码。
  • TSV:规则同 CSV,分隔符换成制表符、LF 换行,不带 BOM。

SQL 文件开头有注释说明来源、条件、排序、导出时间和没导出的字段,并带一句 SET standard_conforming_strings = on;。值以数据库的无损文本输出为准:整数、numeric、浮点、布尔直接写,其余写成字符串字面量,导入时按列类型解析,时间精度、浮点、bytea、数组、json 原文都能原样导回。

用户偏好

在查询页手动执行(点「查询」或回车)且成功的查询,其显示的字段、条件行、排序行(都连同没勾选的草稿)会按「数据源 / 数据库 / 模式 / 表」自动存进 conf.yaml 的 tablePrefs,下次打开这张表自动填好并按它查询;三项都恢复成默认(全部字段、无条件、无排序)再执行一次,这张表的偏好就删掉了。数据源删除后,它名下的偏好和命令窗口的内容可在「更多」菜单里用「清除失效偏好」清掉。

表结构

编辑表

右键表名「编辑结构」(表下的字段、键、索引节点也能打开,打开时选中那一项)打开修改表结构的弹窗(仿 DataGrip 的 Modify Table)。左边是结构树:表 → 列 / 键 / 外键 / 索引 / 检查,工具栏可以新建(Alt+Insert;选中分组时加进这一组,选中表时弹菜单选种类;右键菜单也能新建)、删除(Delete)、复制一份(Ctrl+D)、上移 / 下移(Alt+↑↓);右边是选中项的属性;下面「预览」随改随显示将要执行的 SQL(Alt+P 收起 / 展开,可以在编辑器里打开)。新加的项绿色、改过的蓝色,和原来不同的输入框左边标一道颜色。左右分隔条可以拖动。

  • 表:名称、注释、UNLOGGED、存储参数(fillfactor=90, autovacuum_enabled=false)、访问方法(PG 15+)、表空间、所有者、授权(按角色勾权限,可转授即 WITH GRANT OPTION);分区键、分区边界只读;PG 11 及以前还能切换「有 OID」;
  • 列:名称、注释、类型、默认值、NOT NULL、标识(GENERATED ALWAYS / BY DEFAULT AS IDENTITY)、生成表达式、排序规则。默认值、标识、生成表达式三选一。表名、字段名右边的「aB → a_b」按钮把驼峰命名转成小写下划线(UserName、userName → user_name,LevelA → level_a,Level1 → level_1,连续大写当缩写:HTTPServer → http_server),名称已经是这种写法时不可点。类型、排序规则输入时弹出下拉联想(以输入开头的在前,包含输入的在后),↑↓ 选、回车 / Tab 填入、Esc 收起,↓ 或 Ctrl+Space 列出全部。改类型时数据库不能自动转换的(比如 text 改 integer)填「类型转换」即 USING 后面的表达式;同时改了默认值的,先去掉旧默认值再改类型。已有字段加标识后,序列自动拨到现有最大值之后;已有的普通字段不能改成生成列,PG 13 起才能把生成列改回普通字段,PG 17 起才能改生成表达式。PostgreSQL 不能调整已有字段的顺序,新加的字段排在最后,只有新字段之间能上下移;新字段 NOT NULL 又没有默认值时预览里提醒;
  • 键(主键 / 唯一约束):名称、注释、字段(勾选的先后就是键里的顺序)、INCLUDE(PG 11+)、可延迟;排他约束填完整的 EXCLUDE USING … 定义;
  • 外键:名称、注释、字段、目标表和目标列(不勾选即引用目标表主键)、匹配方式、更新 / 删除时的动作、可延迟;
  • 检查约束:名称、注释、条件表达式、NO INHERIT;
  • 索引:名称、注释、唯一、NULLS NOT DISTINCT(PG 15+)、访问方法、字段或表达式(有「插入字段」下拉)、INCLUDE(PG 11+)、部分索引条件、存储参数、表空间。

名字首尾的空白会去掉;表名、字段名、约束名、索引名超过 63 字节直接列为问题(PostgreSQL 会静默截断)。约束、索引的定义改了就删掉重建(和 DataGrip 一样),只改名称、注释、索引表空间的用 RENAME / COMMENT / SET TABLESPACE。删除字段时,用到它的键、外键、索引、检查约束一并删除(数据库删字段时也会连带删除),底栏会说明删了哪些。

点「确定」(Ctrl+Enter)在一个事务里按顺序执行(先删外键、约束、索引、字段,再改字段、建约束和索引,最后改表本身、改表名),任何一条失败整体回滚,报错里带出错的那条语句,弹窗留着可以接着改。执行时等表锁最多 10 秒,有别的会话占着这张表时报错而不是一直挂着;脚本里有删除字段这种丢数据的操作时要再点一次「确认执行」;改类型、切换 UNLOGGED、换表空间这类会重写整张表的操作在预览里提示。每条语句走扩展查询协议,类型、表达式里夹带的第二条语句执行不了。没有改动时「确定」直接关闭;Esc 关闭,有改动时要在 3 秒内连按两次。执行成功后树上重新加载这张表所在的「表」分组。触发器、规则、行级安全策略、列级权限不在这里编辑。

新建表

模式右键「添加表」打开和「编辑表」同一个弹窗,初始是表名 new_table(重名时加序号)和一个 bigint 的 id 字段做主键。列、键、外键、索引、检查约束、授权的编辑方式和上面一样,另外:可以填分区键(RANGE (…)、LIST (…)、HASH (…))建分区表;字段可以随意上下移,建表时按这个顺序排列;外键的目标表可以选本表(比如 parent_id → id),改表名时跟着改;访问方法可以留默认(PG 12 起才能指定);不支持 WITH OIDS。名称和模式里已有的表、视图、序列、索引重名时直接列为问题,「确定」不能点。

执行顺序:一条 CREATE TABLE(字段、键、检查约束、外键都写在括号里)→ 表注释、字段注释、约束注释 → 索引和索引注释 → 授权 → 所有者不是当前用户时改所有者。全部在一个事务里执行,任何一条失败整体回滚。建好后树上重新加载模式和它下面的「表」分组,展开到新表并选中它。

添加数据库 / 模式

数据源右键「添加数据库」、数据库右键「添加模式」(仿 DataGrip 的 New)。弹窗下方随改随预览将要执行的 SQL,也可以在编辑器里打开;名称和已有的库、模式重名时直接列为问题,「确定」不能点(回车即确定;Esc 关闭,有改动时要在 3 秒内连按两次)。建好后树上只重新加载上一层,展开到新节点并选中它。同一个数据源只开一个「添加数据库」窗,同一个库只开一个「添加模式」窗。

  • 添加数据库:名称(默认 new_database)、注释、所有者、模板、编码、表空间、区域提供者(PG 15+;选 icu 时填 ICU 区域,选 builtin 要 PG 17+)、排序规则(LC_COLLATE)、字符分类(LC_CTYPE)、连接数上限(-1 不限)、允许连接、作为模板,以及授权(CREATE / CONNECT / TEMPORARY,可转授)。模板是新库复制的来源,新库的编码、区域设置默认照搬它:template1 是默认模板,在它里面装的扩展、建的对象新库都会带上;template0 是干净的初始库,要用和模板不一样的编码、区域设置建库时只能选它;也可以选普通库,把它的全部内容复制一份(复制时不能有别的会话连着它)。下拉里每个模板都写出编码和区域设置,下面说明选中的模板是干什么的;编码、排序规则等留空的项,占位文字写出模板的实际值。填的编码、区域设置和所选模板不一样、模板又不是 template0 时,预览里会逐项提醒。CREATE DATABASE 不能放进事务,所以先单独执行,注释、授权随后在一个事务里执行;这一步失败时库已经建好,右下角会提示原因;
  • 添加模式:名称(默认 new_schema,不能以 pg_ 开头)、注释、所有者(不是当前用户时写成 AUTHORIZATION)、授权(USAGE / CREATE,可转授),在一个事务里执行。

名称超过 63 字节报错。所有者就是当前用户时不写 OWNER / AUTHORIZATION;这时建出来的对象默认归当前用户所有,也不需要额外权限。

删除数据库 / 模式 / 表

右键菜单最下面(仿 DataGrip 的 Drop)。先查清楚要删的东西,在确认框里写明大小、里面有什么、谁依赖它(最多列 20 个)、有几个迁移 / 同步任务用到它,以及将要执行的语句,点确认才执行。删完关掉相关的数据查询页、编辑表窗口(删库、删模式还关掉里面的命令窗口和添加模式窗),树上去掉这个节点,重新加载上一层。

  • 删除表:显示估算行数、占用空间;分区表的分区一起删除,不需要 CASCADE。有别的对象直接依赖这张表(视图、物化视图、别的表指过来的外键、继承的子表)时逐个列出,按钮变成「级联删除」(CASCADE;别的表上的外键只删约束本身,不删那张表)。间接依赖(依赖那些视图的视图)不在列表里,级联时也会一起删。确认前没查到、执行时数据库才报出来的依赖(比如用了这张表行类型的函数),会拿数据库列出的依赖再问一次要不要级联。删完重新加载「表」分组和模式;
  • 删除模式:按种类数出模式里的表、视图、序列、函数、自定义类型,以及装在里面的扩展(会被整个删除)。空模式直接删;不空只能连同其中全部对象一起删(CASCADE),别的模式里依赖它们的视图、外键等也会被删除;
  • 删除数据库:显示占用空间和还有几个会话连着。DROP DATABASE 不能放进事务,也不能在连着这个库的会话里执行,所以先关掉自己连这个库的连接池和命令窗口会话,再连到数据源的默认库(删的就是默认库时换 postgres、template1)执行。有别的会话连着时,PostgreSQL 13 起可以断开它们再删(WITH (FORCE)),更早的版本要先让它们断开。删的是数据源的默认库时会提示去编辑数据源换一个,否则连不上。

删表、删模式在一个事务里执行,等表锁最多 10 秒,失败整体回滚。

命令窗口

仿 DataGrip 的 query console:点树上模式、表行尾的「显示命令窗口」按钮,或在视图、函数、视图的字段上右键「显示命令窗口」,在编辑区打开这个模式的 SQL 命令窗口(标签名是 库.模式),每个模式一个,重复打开时切过去。上面是工具栏和 SQL 编辑器,下面是结果区,中间的分隔条可以拖动(键盘 ↑↓ 也行)调整高度。

编辑器与联想

编辑器显示行号,PostgreSQL 语法高亮(颜色跟编辑器主题),括号配对、自动补右括号,查找替换(Ctrl / ⌘+F),多光标、矩形选择,撤销重做,Tab 缩进。Ctrl+/(macOS 上 ⌘+/ 也行)注释 / 取消注释选中的行(行首加 -- )。

联想敲字时自动弹出(点号、:: 后面不用敲字,Ctrl+Space 随时呼出),↑↓ 选、回车填入(Tab 是缩进):

  • FROM / JOIN / UPDATE / INTO / TABLE / TRUNCATE 后面是表和视图(先是命令窗口的模式,再是 public)、模式、数据库;
  • SELECT / WHERE / ON / SET / ORDER BY 等后面是语句里引用的表的字段(悬停看类型、备注)、表的别名、函数,其次是表;
  • 别名.、表名. 后面是字段,模式. 后面是这个模式里的表、视图、函数,库名. 后面是模式,模式.表. 后面是字段;
  • 语句开头是 SELECT、INSERT INTO、CREATE TABLE 之类;刚写完一个名字、值后面是 WHERE、JOIN、AND、AS 之类的关键字(敲小写给小写,否则给大写);DATABASE、SCHEMA 后面是库名、模式名;:: 后面是类型;
  • 候选里显示所属模式、类型、备注;函数填入后补上括号并把光标放进去;名字含大写字母、特殊字符或是关键字时,填入时自动加双引号(在双引号里敲的连引号一起换掉);字符串、注释、数字后面不联想;
  • 库、模式、表和字段第一次用到时才向数据库查,之后缓存;执行了 CREATE / ALTER / DROP / COMMENT / IMPORT 之后重新查,树上这个库(建库、删库时是整个数据源)也跟着刷新。

执行与会话

工具栏:「执行全部」(Ctrl / ⌘+Shift+Enter)执行编辑器里的全部语句;「执行选中」(Ctrl / ⌘+Enter)执行选中的部分,没有选中时执行光标所在的语句(光标在两条语句之间时,跟哪条之间没有空行就算哪条);「停止」取消正在执行的语句,后面的不再执行。语句按分号切分,字符串、带引号的名字、注释、$$ … $$ 函数体、BEGIN ATOMIC … END 里的分号不算;逐条执行,出错即停。

每个命令窗口独占一个数据库会话,第一次执行时才连,search_path 设为这个模式(再加上 public),所以不带模式名的表先在这个模式里找。SET、临时表、没提交的事务在两次执行之间都保留;执行了 BEGIN 还没提交时,工具栏显示「事务未提交」和「提交」「回滚」按钮(事务里出错后只能回滚)。关闭窗口时会话断开,没提交的事务回滚(右下角会提示)。连接断了下次执行自动重连(会话状态随之丢失)。不支持 COPY … FROM STDIN(没有数据可给);COPY … TO STDOUT 只报行数。

日志与结果集

结果区的第一个页签是「日志」,后面跟着这次执行的结果集页签。

  • 日志:每条语句一行——时间、语句、耗时、结果(返回 / 影响了几行,或 完成:CREATE TABLE 之类),报错时写出错误码、出错位置(第几行第几列)、详情、提示、上下文,并在编辑器里标出出错的语句和位置;RAISE NOTICE 等服务端消息跟在结果后面。最多保留最近 100 条,右边有「清空日志」;点一行在编辑器里选中那条语句;
  • 结果集:一次执行里返回数据的语句(SELECT、带 RETURNING 的写语句、SHOW、EXPLAIN……)各一个结果集,页签「结果 1、结果 2……」跟在「日志」后面,点开看表格(只读),页签上的 × 或鼠标中键关闭(关的是正在看的就切到旁边那个,全关掉回到日志);下一次执行返回了数据,就换成新的这一批。执行时每个结果集最多取回 500 行(设置 pgStudio.console.maxRows 可改,最多 10000);写语句的结果超过这个数时语句已经全部执行,日志里说明影响行数未知。值的显示和数据查询页一样(NULL 标出、换行 ↵、超过 2000 字符截断)。点选、拖选、Shift 点选格子,点行号选整行,点表头选整列,点左上角或 Ctrl / ⌘+A 全选,Ctrl / ⌘+C 复制成制表符分隔的文本(Excel 里直接粘贴),选区、复制都只在当前这一页里。有结果集且没出错时自动打开最后一个结果集,否则翻到「日志」。

结果集翻页与导出

每个结果集底部有一条工具栏(跟数据查询页的状态栏一样):左边是总条数和查询耗时,右边是首页 / 上一页 / 下一页 / 末页、每页行数(10 / 20 / 50 / 100 / 500,各结果集共用,记在窗口状态里)和「导出」(CSV / TSV / SQL INSERT)。

  • 全部取回了的结果集直接在取回的行里翻页;
  • 没取完的查询语句(SELECT、WITH、VALUES、TABLE 开头,且语句里没有 INSERT / UPDATE / DELETE / MERGE / INTO 这些词)另开一个只读会话重新执行:先数总条数(最多数 5 秒,超时就只能逐页往后翻、不能跳到末页),翻到取回的行以外的页时把语句包成子查询加 LIMIT … OFFSET … 重新查这一页(每页最多等 30 秒)。只读事务拦住了写数据(nextval、写数据的 WITH、FOR UPDATE 都执行不了),但 pg_notify、pg_advisory_lock 这类有副作用的函数会再跑一遍;只读会话看不到命令窗口会话里的临时表和没提交的改动,没写 ORDER BY 时每次重新查的行序也可能不同;
  • 不是查询的语句(带 RETURNING 的写语句、SHOW、EXPLAIN……)重新执行会再写一遍数据,只能翻取回的行;
  • 导出:全部取回了(也没有被截断的值)直接写取回的行;没取完或有值被截断的查询语句另开只读会话重新执行、一批批写出全部行,通知栏显示进度、可以取消;不是查询的语句只能导出取回的行。默认文件名取目标表名或「模式_query」。SQL INSERT 写进结果集字段来自的那张表(字段都直接取自同一张表或分区表时;生成列不写,GENERATED ALWAYS 的 identity 字段带 OVERRIDING SYSTEM VALUE);字段有算出来的、来自多张表或视图的,表名写成 query_result,导入前自己改。CSV、TSV 的写法跟数据查询页的导出一样。

内容自动保存

编辑器里的 SQL 每隔几秒写回 conf.yaml 的 consoles(按「数据源 / 数据库 / 模式」),执行前、关闭窗口时、Ctrl / ⌘+S 时立即写,下次打开原样恢复;清空内容就删掉这条记录。超过 1 MB 的内容不再自动保存。数据源删除后,它名下命令窗口的内容可在「更多」菜单里用「清除失效偏好」清掉。删除数据库、模式时关掉里面的命令窗口;删库前先断开命令窗口连着这个库的会话。

迁移与同步

任务文件夹

「迁移」「同步」两页的工具栏有【新建文件夹】【新建任务】两个按钮,任务都放在文件夹里;还没有文件夹时保存任务会自动新建「默认」文件夹。

  • 单独执行:任务行上的 ▶(执行中变成「停止」);行尾还有「编辑」「删除」,双击或回车编辑,Delete 删除,执行中不能删。右键还有「复制任务」(名称加「副本」,不带执行记录)、「上移 / 下移」、「显示日志」;
  • 执行文件夹:文件夹行上的 ▶,按文件夹内的顺序逐个执行。某个任务失败或被停止后,后面的任务不再执行(同一文件夹里的任务往往前后有依赖,比如先迁主表再迁明细表);结束时汇总成功几个、在哪个失败、几个未执行。迁移文件夹执行前只确认一次,列出全部会被删除重建的目标表(最多列 12 张);
  • 状态:行图标区分未执行 / 执行中 / 成功 / 失败 / 已取消,悬停看上次执行的时间、行数、用时、提醒;文件夹描述显示任务数和上次执行的统计;执行时行尾显示进度百分比,右下角有可取消的进度通知,成功但有提醒时通知标黄。执行中可以停止单个任务,也可以停止整个文件夹;文件夹在执行时里面的任务不能再单独执行;确认框开着时再点一次「执行」也会被挡住;
  • 调整顺序:拖动任务(文件夹内排序或拖进别的文件夹)、拖动文件夹;右键菜单的「上移 / 下移」;或在「编辑文件夹」弹窗里排执行顺序;
  • 复制文件夹:文件夹行上的复制按钮(或右键菜单):
    • 「复制文件夹」:在同一页复制一份,名称加「副本」(重名时再加序号),排在原文件夹后面;
    • 「复制到同步… / 复制到迁移…」:把文件夹里的任务配置复制到另一页,可以新建同名文件夹(重名时加序号),也可以添加到已有文件夹(源表、目标表都相同的任务跳过)。源表、目标表、任务名、每批行数照搬,执行记录不带;迁移专有的选项(字段顺序、是否迁数据、外键)复制到同步时去掉;同步条件复制到迁移时去掉(迁移不支持条件,会迁移全部行,复制前会提示),迁移选项取默认值。复制完自动切到目标页并选中文件夹;
  • 删除文件夹(右键):连同里面的任务一起删,有任务在执行时不能删。

新建任务

迁移、同步两页的文件夹行上都有两个新建按钮(右键菜单、工具栏【新建任务】的下拉菜单、空白处右键菜单里也是这两项),任务放进这个文件夹;任务表单里也可以改「所属文件夹」:

  • 批量任务(乘号图标):源表是勾选列表(可筛选、全选),勾几张都按批量创建——每张表建一个任务,任务名、目标表名都取表名,按勾选顺序放进文件夹(这也是执行文件夹时的顺序),文件夹里已有同样源表和目标表的任务跳过。表单会逐表列出检查结果(迁移:目标表已存在会被重建 / 将新建;同步:目标模式里有没有同名表、字段按名称对应、主键、同步条件),有不合格的表就不让创建;源和目标是同一个模式时不能创建(同名表就是同一张表);迁移勾了分区表也不能创建。迁移的字段按源表顺序(建好后可以逐个编辑调整)。「创建并执行」按顺序只执行这一批;
  • 单表任务(加号图标):源表是下拉框,只能选一张;可以改任务名(留空取源表名)、目标表。迁移可以调整迁移后的字段顺序、预览 SQL;同步的目标表可以不同名,显示按名称对应的字段映射。数据源树上表的右键「以此为源表新建迁移任务 / 同步任务」也是单表任务。

表单里每批行数 1–50000,默认 1000。同一数据源,或主机、端口相同的两个数据源指向同一张表,都算「源表与目标表相同」,不能保存。「保存并执行」(回车也是)保存后关窗再执行。没有数据源时打开任务表单会提示先去添加。

迁移

单表任务弹窗里选源表和目标表(数据源 → 数据库 → 模式 → 表),目标表名可以手填(下拉提示已有的表),不存在就新建。字段顺序:列出源表全部字段,拖动或用箭头(Alt+↑↓)调整目标表中的字段顺序,「恢复源表顺序」一键还原。字段名不变,按名称一一对应;之后源表新增的字段排在末尾。「预览 SQL」浮层可以复制或在编辑器里打开将要执行的完整脚本,不改动任何东西。

执行步骤:

  1. 读取源表定义(源库会话只读);
  2. 目标库一个事务内(等表锁最多 30 秒):DROP TABLE IF EXISTS 目标表,按源表定义建表(字段类型、排序规则、默认值、NOT NULL、identity、生成列、主键 / 唯一 / 排他 / 检查约束、UNLOGGED、存储参数;serial 字段在目标模式新建同参数的序列并 OWNED BY;检查约束的 NOT VALID 去掉),写表备注、字段备注、约束备注,再创建普通索引(含表达式索引、部分索引、INCLUDE)并写索引备注。先建索引,后插入数据:结构一次性完整落地,这一步任何地方失败都会整体回滚,目标表保持原样;
  3. 勾选「迁移数据」时分批写入,写入时所有索引(含唯一索引)都已生效:源表有主键时按主键分批 INSERT … ON CONFLICT (主键) DO UPDATE;没有主键时用游标按物理顺序读、直接 INSERT;
  4. 校准 serial / identity 序列:不小于源序列当前值和导入数据的最大值;
  5. 勾选「迁移外键约束」时补建外键(引用的表须已存在于目标库,建不上只提示不中断);自引用外键指向新表。外键放在数据之后,因为自引用的父行不一定先导入。不勾时每个外键作为提醒列出;
  6. ANALYZE 目标表。

索引、约束、序列名里含源表名的,会换成目标表名(users_pkey → users_bak_pkey;只换整段,表叫 t 时 created_at_idx 不动),与目标模式里已有的名字重复时加 _1 后缀。执行前默认弹窗确认(设置 pgStudio.migration.confirmBeforeRun 可关闭)。

同步

源表、目标表都要已存在。字段严格按名称对应(区分大小写),两边字段顺序不同不影响:

  • 两边都有的字段:同步;类型写法不同时按目标类型转换,转换失败(例如目标字段更短)会报错,不会静默截断;
  • 只有目标表有的字段:不写入(新行取默认值,已有行保持原值);NOT NULL 又没有默认值的在表单里警告;
  • 只有源表有的字段:忽略;
  • 目标表的生成列:由目标库计算;目标表 GENERATED ALWAYS 的 identity 字段不参与更新,写入时带 OVERRIDING SYSTEM VALUE。

冲突键是目标表的主键(必须在源表中有同名字段,目标表没有主键不能同步),INSERT … ON CONFLICT (主键) DO UPDATE。源表没有主键时用游标按物理顺序读。同步结束后把目标表的 serial / identity 序列拨到不小于最大值,避免之后在目标库插入时撞主键。表单里会预览字段映射、冲突键和问题提示。

同步条件(可选):只同步源表中满足条件的行,写 WHERE 后面的部分,例如 "flagDelete" = false、updated_at >= now() - interval '7 days' AND status <> 'draft'。

  • PostgreSQL 会把不加引号的字段名转成小写:字段名含大写字母(建表时加了引号)的,条件里也要加双引号。写错时会提示正确写法;
  • 表单里「检查条件」会在源表上校验,并报出满足条件的行数(数超过 5 秒只报条件有效);
  • 执行前先校验条件,写错了在写入任何数据之前就报错;
  • 条件只决定读哪些源行:源表里后来不再满足条件的行(比如 flagDelete 改成了 true),目标表里已有的那行不会被删除或更新;
  • 安全:带条件的查询一律走扩展查询协议(一次只能执行一条语句,夹带 ; DROP … 会被拒绝),源库会话设为只读(条件里调用会写数据的函数也写不进去)。

数据传输

迁移、同步共用的读写方式:

  • 读:有主键时按主键 keyset 分页(WHERE (pk) > (上一批末行) ORDER BY pk LIMIT n),每批一条独立语句,不在源库挂长事务;没有主键时用只读事务里的游标;
  • 写:每批一条 INSERT … SELECT … FROM unnest($1::text[], $2::text[], …) ON CONFLICT …,参数个数等于字段数,和行数无关;
  • 所有值以 PostgreSQL 的文本格式原样往返(会话固定 DateStyle = 'ISO, YMD'、IntervalStyle = postgres、extra_float_digits = 3、bytea_output = hex、standard_conforming_strings = on、client_encoding = UTF8、statement_timeout = 0),浮点极值、时间戳微秒、numeric、bytea、数组、json 原文都不经过 JS 类型转换;
  • 读下一批和写当前批并行进行;进度的总行数取统计信息的估算值(超过 500 万行或带同步条件的大表不精确数);
  • 执行中可以在通知或列表行上停止,每一步写进「输出 → PostgreSQL Studio」。

设置项与命令

设置(pgStudio.*):

设置项 默认 说明
ui.dialogWindow float 数据源、任务、编辑表、添加库 / 模式这些弹窗在独立窗口(float)还是编辑器标签页(tab)里打开
migration.confirmBeforeRun true 执行迁移任务前弹窗确认(迁移会先删除目标表)
console.maxRows 500 命令窗口执行时每个结果集最多取回的行数(1–10000)

命令面板(分类「PostgreSQL Studio」):添加数据源、添加迁移任务、添加同步任务、打开配置文件 conf.yaml、重新加载配置、显示日志。

配置文件

~/.x1/postgresql-studio/conf.yaml(目录 0700、文件 0600,密码为明文):

version: 2
datasources:
  - id: 3f2a9c1b7e04
    name: 本地开发库
    host: 127.0.0.1
    port: 5432
    user: postgres
    password: secret          # 纯数字的密码要加引号,不然会被 YAML 当成数字
    database: postgres
    ssl: disable              # disable | require | verify-full
migrations:                   # 文件夹 → 任务;tasks 的顺序就是执行文件夹时的顺序
  - id: 5c6d7e8f9a0b
    name: 用户数据
    tasks:
      - id: 9b1c2d3e4f50
        name: users → users_bak
        source: { datasourceId: 3f2a9c1b7e04, database: app, schema: public, table: users }
        target: { datasourceId: 3f2a9c1b7e04, database: app, schema: archive, table: users_bak }
        columnOrder: [id, name, email, created_at]
        migrateData: true
        includeForeignKeys: false
        batchSize: 1000
        lastRun: { at: '2026-09-23T12:00:00.000Z', status: success, rows: 2480, durationMs: 1830 }
syncs:
  - id: 1a2b3c4d5e6f
    name: 报表
    tasks:
      - id: 0a1b2c3d4e5f
        name: orders 同步
        source: { datasourceId: 3f2a9c1b7e04, database: app, schema: public, table: orders }
        target: { datasourceId: 3f2a9c1b7e04, database: report, schema: public, table: orders }
        where: '"flagDelete" = false'    # 可选:同步条件
        batchSize: 1000
tablePrefs:                   # 数据查询页的用户偏好:每张表上次执行查询时的显示字段、条件行、排序行
  - datasourceId: 3f2a9c1b7e04
    database: app
    schema: public
    table: orders
    select: [id, status, amount]   # 不写表示全部字段
    conditions:                    # WHERE 条件行,按显示顺序,勾选的用 AND 拼接
      - text: status = 'paid'
        enabled: true
      - text: amount > 1000        # enabled: false 是草稿,不参与查询;一行也可以直接写字符串,算勾选
        enabled: false
    sorts:                         # ORDER BY 排序行,从上到下就是排序的先后,勾选的用逗号拼接
      - text: created_at DESC
        enabled: true
consoles:                     # 命令窗口的内容:每个模式一份
  - datasourceId: 3f2a9c1b7e04
    database: app
    schema: public
    sql: |
      SELECT * FROM orders WHERE status = 'paid';
      -- 草稿
      UPDATE orders SET status = 'done' WHERE id = 1;

可以手工编辑,保存后插件自动重新读取(等 300 毫秒没有新改动再读,免得读到写了一半的文件;或在「更多」菜单里「重新加载配置」)。写回时先写临时文件再改名,不会留下半截文件;tablePrefs、consoles 为空时不写;不认识的顶层键原样保留。数据源缺 name 取主机名,缺 port / user / database 取默认值;缺必填字段的条目忽略并记进日志。无法解析的文件会被改名为 conf.yaml.broken-<时间>,不会被覆盖。

早期版本(version: 1)的 migrations / syncs 是平铺的任务列表,读取时自动归入「默认」文件夹,下次保存即写成上面的两层格式。更早的 tablePrefs 只有 where、orderBy 两个字符串,读取时各当作一行勾选的条件、排序,下次保存即写成 conditions、sorts。

限制

  • 支持 PostgreSQL 10 及以上;
  • 分区表不能作为迁移源(同步可以);
  • 字段用到的自定义类型(枚举、复合类型、域)须已存在于目标库;
  • 表的属主、权限、触发器、规则、行级安全策略不迁移;
  • 浏览用的连接每个库最多 3 条,空闲 60 秒断开;迁移、同步、导出、命令窗口各自另开连接。

开发

npm install
npm run compile          # 开发构建
npm run watch            # 监听构建(F5 调试用)
npm run check-types      # 类型检查(扩展 + webview)
npm test                 # 配置存储 + SQL 切分与联想、导出格式 + webview 前端
npm run package          # 类型检查 + 生产构建
./build.sh               # 打包 VSIX(也可以 npm run vsix)
npm run dev:link         # 把本仓库软链到 ~/.vscode/extensions,重载窗口即生效(dev:unlink / dev:status / dev:check)
python3 scripts/render-icon.py   # 改了 media/icon.svg 后重新生成 media/icon.png(仅 macOS)
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft