ToolJet 数据库查询实战指南:GUI 模式、SQL 编辑器、联表与 JSON 查询全解析
2026/9/10 13:25:18 网站建设 项目流程

ToolJet 数据库查询实战指南:GUI 模式、SQL 编辑器、联表与 JSON 查询全解析

【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet

本指南以 ToolJet 开源仓库中 querying-tooljet-db.md 为核心骨架编写。ToolJet Database(以下简称 TJDB)是 ToolJet 内置的托管式 PostgreSQL 数据库,可直接作为数据源在查询面板中使用。读完本文,你将掌握:通过 GUI 模式完成增删改查与聚合分组、在 SQL 编辑器中安全执行 DML 语句、处理外键约束、实现多表 Join、格式化日期时间列,以及查询 JSON 类型字段的完整方法。

ToolJet Database 与其他数据源的使用体验完全一致——只需在查询面板添加一条查询并选择ToolJet Database作为数据源,即可通过GUI 模式(可视化表单)或SQL 编辑器(手写 SQL)两种方式操作数据。后端实现上,GUI 模式通过 TooljetDbDataOperationsService 将操作翻译为 PostgREST 请求,而 SQL 模式则经由 node-sql-parser 做 AST 解析与白名单校验后,直连工作区专属的 PostgreSQL schema 执行,两层路径都值得深入理解。

GUI 模式:可视化操作数据

GUI 模式适合不熟悉 SQL 的用户,也适合把操作绑定到按钮、表单等组件事件上,实现"零代码"数据交互。

  1. 打开查询面板,点击+Add按钮新建查询,数据源选择ToolJet Database
  2. 通过编辑器顶部的切换开关选择GUI mode
  3. 选择要查询的操作(operation),并根据所选操作填写对应参数;
  4. 点击Run执行查询。

注意:所选操作必须符合目标表的列约束(如必填字段、数据类型、外键等),否则执行会报错。

GUI 模式下可选操作与后端run()方法中的操作分派一一对应(见 tooljet-db-data-operations.service.ts):list_rowscreate_rowupdate_rowsdelete_rowsjoin_tablessql_execution,以及面向批量写入的bulk_update_with_primary_keybulk_upsert_with_primary_key。前端的对应编辑器组件集中在 frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/ 目录下(ListRows.jsxCreateRow.jsxUpdateRows.jsxDeleteRows.jsxJoinTable.jsx等)。

List Rows(列出记录)

返回表中的全部记录,是 GUI 模式下最常用的操作。全部参数均为可选

  • Filter(过滤):选择列、操作符(operator)与值来过滤记录。GUI 上的操作符最终由 PostgrestQueryBuilder 翻译成 PostgREST 语法,支持eq(等于)、neq(不等于)、gt/gte/lt/lte(大小比较)、like/ilike(模糊匹配)、is(空值判断)、in(在集合内)、contains/containedBy(包含关系)、全文检索textSearch等;
  • Sort(排序):选择列与排序方向(升序 ascending / 降序 descending),对应后端order=column.asc形式的查询参数;
  • Limit(限制):限制返回的记录条数。后端会对 limit 做整数校验(listRows 实现),非整数会抛出 "Limit should be a valid integer" 错误;
  • Aggregate(聚合):对一组值执行计算并返回单个结果,可用函数为CountSum。注意限制:
    • Sum 仅适用于数值列
    • Count 仅统计非空值
    • 后端实现见 buildAggregateAndGroupByQuery,聚合会生成table_column_sum:column.sum()形式的 PostgREST 别名查询;
  • Group By(分组):按指定列的值进行分组。使用约束:
    • 必须先添加至少一个聚合条件才能使用;
    • 可选择一个或多个分组列;
    • 结果按所选列的值组合(唯一组合)分组。

从源码看,过滤条件会先经过hasNullValueInFilters检查:除is操作符外,任何值为null的过滤条件都会被拒绝(tooljet-db-data-operations.service.ts),提示改用IS操作符判断空值——这是 GUI 模式下值得留意的行为细节。

Create Row(创建记录)

向表中插入新记录,支持一次创建单条或多条记录

必填参数

  • Columns(列):选择要写入的列并填写值;点击+Add column按钮可以追加新的列字段。

后端createRow会将表单中所有非空列组装成{ column: value }对象,并通过 PostgREST 代理以POST方式发送到/api/tooljet-db/proxy/{tableId}(createRow 实现)。

Update Row(更新记录)

更新表中已有记录,支持一次更新单条或多条记录

必填参数

  • Filter(过滤):通过列 + 操作符 + 值指定要更新的目标记录;
  • Columns(列):选择要修改的列并填写新值。

后端对应update_rows,通过buildPostgrestQuery将过滤条件拼进查询串,并以PATCH方式提交更新体(updateRows 实现)。

Delete Row(删除记录)

从表中删除记录,支持一次删除单条或多条记录

必填参数

  • Filter(过滤):通过列 + 操作符 + 值指定要删除的目标记录;
  • Limit(限制):限制删除的记录条数(默认值为 1)。

后端deleteRows有一个安全设计:如果既没有过滤条件也没有 limit,操作会被直接拒绝(返回 "Please provide a where filter or a limit to delete rows"),防止误删整表数据(deleteRows 实现)。GUI 模式要求至少提供过滤条件,而这一后端兜底逻辑同样保护了 SQL 之外的所有调用路径。

SQL 编辑器:直接编写 DML 语句

ToolJet 的SQL 编辑器允许你手写标准 SQL 查询 ToolJet Database,语法基于 PostgreSQL。它当前明确只支持 DML(数据操纵语言)命令

  • 支持的命令
    • SELECT:检索数据;
    • INSERT:插入新记录;
    • UPDATE:修改已有数据;
    • DELETE:删除记录。
  • 受限命令
    • DDL(数据定义语言)CREATEALTERTRUNCATEDROPRENAME等一律不允许;
    • DCL(数据控制语言)GRANTREVOKE同样被禁止。

这一限制并非只停留在文档层面。后端 checkCommandAllowlist 定义了一个白名单['select', 'insert', 'update', 'delete', 'transaction'],任何 SQL 经 node-sql-parser 解析成 AST 后,若type不在白名单内就会抛出 "This SQL functionality is restricted."。也就是说,即便绕过界面直接调用 API,DDL/DCL 也无法执行。

使用步骤

  1. 在查询面板点击+Add新建查询,选择ToolJet Database
  2. 在查询编辑器中选择SQL模式标签页;
  3. 在编辑器中编写 SQL 语句;
  4. 点击Run执行。

示例:

SELECT * FROM users WHERE age > 30

SQL 模式的底层执行链路

了解 SQL 模式如何执行,有助于你写出更符合平台预期的查询。从 sqlExecution 的实现可以看到完整链路:

  1. 模式开关检查isSQLModeDisabled()返回true时直接拒绝执行。判断逻辑为环境变量TJDB_SQL_MODE_DISABLE === 'true'或当前版本为 Cloud 版(tooljet_db.helper.ts)。自托管(Self-hosted)环境默认启用 SQL 模式;
  2. 建立租户连接:读取工作区的 TJDB 配置,解密数据库密码,并定位工作区专属 schema(格式为workspace_{organizationId},SQL 模式禁用时回退为public,见 findTenantSchema);
  3. SQL 解析:使用node-sql-parser的 PostgreSQL 方言解析语句,语法错误会返回 "Syntax error encountered";
  4. 命令白名单校验:按checkCommandAllowlist拦截非 DML 语句;
  5. 表存在性验证verifyTablesExistInWorkspace会核对 SQL 中引用的每个表是否确实存在于当前工作区,否则抛出 "Table: xxx not found";
  6. 权限验证validateSchemaAndTablePrivileges通过 PostgreSQL 的has_schema_privilege/has_table_privilege检查租户用户对 schema 与表的访问权限;
  7. 表名替换parseTableNameInAST将 AST 中的逻辑表名替换为内部表 ID,随后重新生成 SQL 并执行;
  8. 执行完成后销毁连接,错误则统一封装为 ToolJetDatabaseError 返回。

值得注意的是,SQL 模式支持事务transaction在白名单中),适合需要多语句原子操作的场景。

处理带外键约束的表

ToolJet Database 支持表间外键(Foreign Key)关系。当对带外键约束的表执行创建、更新或删除时,必须保证不违反外键约束:

  • 源表(source table)中创建/更新记录时,外键值必须已存在于目标表中,否则操作失败并返回错误信息;
  • 目标表(target table)中删除记录时,必须确保该记录没有被源表引用,否则同样会失败。

多表 Join(联表查询)

通过Join操作可以将 ToolJet Database 中的两张或多张表连接起来查询。

必填参数

**From(连接来源)**部分包含以下参数:

  • Selected Table(选中表):选择要参与连接的主表;
  • Type of Join(连接类型):可选Inner Join(内连接)、Left Join(左连接)、Right Join(右连接)、Full Outer Join(全外连接);
  • Joining Table(连接表):选择要与主表连接的另一张表。如果选中表与其他表存在外键关系,这些表会以带外键图标的形式列出;
  • On(连接条件):分别选择主表列连接表列作为连接键。目前仅支持=操作符。若两表存在外键关系,两侧列会自动填充到下拉框中;
  • AND / OR 条件:每个 Join 下方可通过+Add more按钮添加多个连接条件,条件之间用ANDOR组合。

可选参数

  • Filter(过滤):与List rows操作支持相同的过滤操作,添加条件(列 + 操作符 + 值)即可;
  • Sort(排序):选择列与升/降序排序响应;
  • Limit(限制):限制返回的记录条数;
  • Offset(偏移):跳过前 N 条记录,用于分页(与 Limit 搭配);
  • Select(选择列):选择响应中要返回的列,默认返回全部列。

后端实现上,joinTables与前几种操作不同:它不经过 PostgREST 代理,而是将 Join 配置 JSON 交给TooljetDbTableOperationsService的表操作流程生成查询(joinTables 实现)。源码中还会对 From、Select/Aggregate 等必填区块做空值校验,并清理空的过滤/排序/分组条件,因此提交空的 Join 配置会得到明确的 "Input can't be empty" 或区块级错误提示。

将日期时间列映射到 Table 组件

ToolJet Database 中的日期时间列ISO 8601 格式存储。查询返回时该列默认也以 ISO 8601 格式显示。若想在 Table 组件中以更可读的格式展示,请按以下步骤操作:

  1. 将查询连接到 Table 组件,打开其属性面板
  2. Columns部分选中存储日期时间的列;
  3. 将该列的类型从String改为Date Picker
  4. 在日期格式区域,按需打开Enable date(启用日期)与Enable time(启用时间)开关;
  5. 在**转换(transformation)**字段中:{{cellValue}}变量保存着 ISO 8601 格式的原始值,先用{{new Date(cellValue)}}将其转换为 Date 对象,再按需格式化。

这种"先new Date()再格式化"的思路充分利用了 ToolJet 内建的双花括号表达式能力,可以搭配任意日期格式化函数实现自定义展示。

查询 JSON 数据类型

ToolJet Database 支持将列设置为JSON 数据类型,用于存储数组、嵌套对象等结构化数据,非常适合保存配置、日志等复杂结构。查询 JSON 列的方式取决于数据结构是扁平还是嵌套。

扁平 JSON 对象(Flat JSON Object)

扁平 JSON 指所有键值对都处于同一层级、没有嵌套的 JSON 结构——每个键唯一,所有值都是直接数据条目。

操作步骤:

  1. 从查询面板添加ToolJet DB作为数据源;
  2. 选择GUI 模式(也可选择 SQL 模式);
  3. 选择表名
  4. 从下拉框选择所需操作
  5. 点击 Filter 前的+ Add Condition按钮;
  6. 选择包含 JSON 数据的列、期望的操作符并输入值;
  7. 在列名下方的输入框中,通过在键名前加->>来指定要访问的键,例如->>city

响应示例

[ { "id":1, "json":{ "id":101, "age":30, "city":"Los Angeles", "name":"Alice Johnson", "email":"alice@example.com", "country":"USA" } } ]

嵌套 JSON 对象(Nested JSON Object)

嵌套 JSON 指部分值本身又是 JSON 对象或数组的多层级结构,能够表达元素之间复杂的层次关系。

操作步骤:

  1. 从查询面板添加ToolJet DB作为数据源;
  2. 选择GUI 模式(也可选择 SQL 模式);
  3. 选择表名
  4. 从下拉框选择所需操作
  5. 点击 Filter 前的+ Add Condition按钮;
  6. 选择包含 JSON 数据的列、期望的操作符并输入值;
  7. 在列名下方的输入框中,通过在每个键名前加->来指定完整的 JSON 路径,例如->user->preferences->settings->notifications->sms->alerts->appointments->cancellations

技巧->用于访问嵌套 JSON 字段(返回 JSON 值),->>用于访问文本(返回文本值)。扁平对象取文本用->>,嵌套对象逐层下钻用->

响应示例

[ { "id": 102, "name": "Michael Brown", "age": 25, "email": "michael@example.com", "user": { "preference": { "settings": { "notification": { "sms": { "alert": false } } } } } }, { "id": 104, "name": "David Miller", "age": 35, "email": "david@example.com", "user": { "preference": { "settings": { "notification": { "sms": { "alert": false } } } } } } ]

JSON 路径语法与 PostgreSQL 原生的->/->>运算符一致。在 buildPostgrestQuery 中可以看到,过滤条件支持可选的jsonpath字段:当提供了jsonpath时,查询列名会被拼接为column->>city这样的形式(即column + jsonpath),这正是 GUI 界面中输入->>city后底层的处理方式——理解这一点,你就明白为什么 SQL 模式下可以直接写出WHERE contenteditable="false">【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询