ToolJet Database Editor:可视化建表、CSV 批量导入与数据过滤的完整实践指南
【免费下载链接】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 Database 是 ToolJet 内置的托管式数据层,Database Editor 则是直接管理它的可视化工作台。本篇基于仓库中的官方文档 Database Editor 与配套前后端源码,完整讲清建表与列约束、行级编辑、CSV 批量上传的 Upsert 语义、过滤(Filter)与排序(Sort)的操作方法,并延伸到服务端真实接口与查询构建链路,帮助你在不写 SQL 的前提下把 ToolJet Database 当作生产可用的内部应用数据底座。
Database Editor 总览
ToolJet Database 将数据组织为表(tables),每张表可以有不同结构。打开 Database Editor 后,所有表按字典序(lexicographically)列在左侧,点击任一表即可查看其数据;左侧边栏(Sidebar)可以收起,为数据编辑区腾出更多空间。
从源码结构看,这一前端模块位于 TooljetDatabase 目录,目录划分与界面功能一一对应:
| 目录 | 对应功能 |
|---|---|
| TableList / TableListItem / Sidebar | 左侧表列表与可折叠侧边栏 |
| Table / Drawers / Forms | 数据表格、右侧抽屉式编辑面板与表单 |
| Filter / Sort / Search / Menu | 过滤、排序、搜索与表格菜单 |
| usePostgrestQueryBuilder.jsx | 把 Filter/Sort/分页条件拼装成 PostgREST 查询串 |
与之配合的服务端接口集中在 tooljet-db 控制器,例如GET /tooljet-db/organizations/:organizationId/tables(列表)、POST /tooljet-db/organizations/:organizationId/table(建表,带TableCountGuard与FeatureAbilityGuard双重守卫)、POST .../bulk-upload(CSV 上传)等。可见界面上的每个动作都有明确的 REST 端点支撑,且全部经过组织级鉴权。
创建新表(Create New Table)
在 ToolJet Database 中创建新表的步骤:
- 点击 Database Editor 左上角的Create New Table按钮;
- 右侧会滑出一个抽屉(drawer),在其中填写新表的详情。
创建一张新表需要:
- 输入Table name(表名);
- 默认会自动创建一个id列,数据类型为serial,并作为表的主键(primary key);你可以把主键改成其他列(支持复合主键)。
列定义选项(Add Columns)
| 选项 | 说明 |
|---|---|
| Column name | 为列输入一个唯一名称。 |
| Data type | 从下拉菜单中选择合适的数据类型。支持的类型详见 Supported Data Types 一节。 |
| Default value (optional) | 指定列的默认值。留空时该列允许为 null。 |
| Primary Key | 勾选后将该列设为主键;可以同时勾选多列,构成复合主键。详见 Primary Key。 |
| NULL/NOT NULL toggle | 控制列是否允许 null 值;默认允许 null。 |
| Unique toggle | 点击 kebab 菜单打开Unique开关,为该列添加唯一约束,保证所有值互不相同;默认允许重复。 |
| Foreign Key | 点击+ Add Relation建立外键关系,把本列链接到另一张表的主键或唯一约束列。详见 Foreign Key。 |
前端提交后,请求会命中服务端 createTable 端点,最终委托TooljetDbTableOperationsService.perform(organizationId, 'create_table', ...)在对应组织的租户 schema 下执行建表。
列约束(Column Constraints)
ToolJet Database 支持多种列约束,用于维护数据完整性、对表中存储的数据强制规则:
Primary Key(主键):保证指定列(组)的值在全表所有行中唯一且非空,作为每条记录的唯一标识。
Foreign Key(外键):在两张表的数据之间建立链接,保证引用完整性——要求源表外键列(组)的值必须匹配目标表主键或唯一约束列(组)中的值。
- Source Table(源表):要添加约束的当前表;
- Target Table(目标表):包含被引用列的表。
Unique(唯一):保证指定列(组)的值在全表中唯一,但允许 null 值。
Not Null(非空):保证指定列不允许 null 值,每行都必须提供取值。
各数据类型与约束的允许组合(摘自 Permissible Constraints per Data Type 表):
| 数据类型 | Primary Key | Foreign Key | Unique | Not Null |
|---|---|---|---|---|
| serial | 允许 | 不允许 | 允许 | 允许 |
| varchar | 允许 | 允许 | 允许 | 允许 |
| int | 允许 | 允许 | 允许 | 允许 |
| bigint | 允许 | 允许 | 允许 | 允许 |
| float | 允许 | 允许 | 允许 | 允许 |
| boolean | 不允许 | 不允许 | 不允许 | 允许 |
| date with time | 不允许 | 不允许 | 不允许 | 允许 |
| jsonb | 不允许 | 不允许 | 不允许 | 允许 |
从这张表可以看出:只有 varchar/int/bigint/float 这类“值类型”可以承担主键、外键与唯一约束;boolean、时间戳、jsonb 只能使用 Not Null 约束,这也是建表设计外键时必须牢记的边界。
添加与修改数据(Adding and Modifying Data)
添加数据入口(Add New Data)
数据编辑区顶部的Add new data按钮提供两种写入方式:新增单行(Add new row)与批量上传(Bulk upload data)。
新增一行(Add New Row)
点击顶部的Add new data按钮并选择Add new row,或者点击表格左下角的+按钮。右侧会打开一个抽屉,在其中填写新行的各列值。
编辑整行(Edit Row)
将鼠标悬停在要编辑的行上,该行复选框旁会出现展开(expand)图标;点击该图标打开抽屉,即可编辑整行数据。
编辑单个单元格(Edit a Cell)
- 双击要编辑的单元格;
- 输入新值;
- 点击Save按钮或按Enter保存修改;
- 布尔类型列使用开关(toggle)切换取值。
批量上传 CSV(Bulk Upload Data)
点击数据编辑器顶部的Bulk upload data按钮,右侧滑出抽屉后即可上传一个CSV文件向表中插入记录。其写入语义是Upsert:
- 若某行缺少 id 列数据,则按行数据插入一条新记录;
- 若id 已存在,则用行数据更新对应记录。
抽屉中还可以下载模板 CSV 文件:既可以按模板填写待上传数据,也可以把自有 CSV 整理成与模板相同的格式。文件就绪后,通过文件选择器选中文件(或拖拽进选择器),再点击Upload data完成上传。
要求(Requirements):
- CSV 各列的数据类型必须与 ToolJet Database 表中的列类型匹配;
serial类型的id列不能包含重复值;- 必须满足所有列约束,例如标记为
Unique的列在 CSV 中不得出现重复值。
限制(Limitations):
- 单个 CSV 文件最多 1000 行;
- CSV 文件大小上限为 5 MB(服务端默认值;文档“Limitations”条目中写作 2 MB,与源码默认值不一致,以源码为准)。
在自托管版本中,可通过以下环境变量突破上述限制:
TOOLJET_DB_BULK_UPLOAD_MAX_ROWS:最大上传行数,默认 1000 行;TOOLJET_DB_BULK_UPLOAD_MAX_CSV_FILE_SIZE_MB:批量上传的最大 CSV 文件大小(MB),默认 5 MB。
源码视角:批量上传的真实执行链路
前端把 CSV 以 multipart 形式提交到POST /tooljet-db/organizations/:organizationId/table/:tableName/bulk-upload。控制器先做文件体积校验:
// server/src/modules/tooljet-db/controller.ts this.MAX_CSV_FILE_SIZE = process.env?.TOOLJET_DB_BULK_UPLOAD_MAX_CSV_FILE_SIZE_MB && !isNaN(Number(process.env.TOOLJET_DB_BULK_UPLOAD_MAX_CSV_FILE_SIZE_MB)) ? 1024 * 1024 * Number(process.env.TOOLJET_DB_BULK_UPLOAD_MAX_CSV_FILE_SIZE_MB) : 1024 * 1024 * 5; // 5MB超过上限直接抛出File size cannot be greater than ...MB的 400 错误。
校验通过后进入 TooljetDbBulkUploadService,核心逻辑与文档描述完全吻合:
- 行数上限在构造函数中读取
TOOLJET_DB_BULK_UPLOAD_MAX_ROWS(非法值回落到 1000),流式解析时一旦超过即抛出Row count cannot be greater than ...; - 使用
fast-csv流式解析并开启strictColumnHandling,校验表头必须是表列名的子集(Columns ... not found in table); - 逐行做类型转换校验:boolean 只接受
true/false,integer/double precision/bigint 按各自规则解析,jsonb 执行JSON.parse; - 用集合检测 CSV 内部的主键重复,命中即报
Duplicate primary key found on row[n]; - 全部校验通过后,在单条事务中执行批量 INSERT ... ON CONFLICT (主键) DO UPDATE SET ...,并对
serial列(默认值形如nextval(...))写入DEFAULT让数据库自动取号——这正是文档所说“id 缺失则插入、id 存在则更新”Upsert 语义的实现。
删除记录(Delete Records)
删除一条或多条记录:勾选目标记录左侧的复选框,选中任意一条后顶部会出现删除按钮,点击Delete record即可删除所选记录。
过滤数据(Filter)
添加过滤器(Add Filter)
点击数据编辑器顶部的Filter按钮即可为表添加任意多个过滤器。每个过滤器由三部分组成:
- 从 Columns 下拉中选择一个column(列);
- 选择一个operation(操作符);
- 为该操作符输入一个value(值)。
可用操作符(Available operations)
| 操作符 | 说明 |
|---|---|
| equals | 判断列值是否等于输入值。 |
| greater than | 判断列值是否大于输入值。 |
| greater than or equal | 判断列值是否大于或等于输入值。 |
| less than | 判断列值是否小于输入值。 |
| less than or equal | 判断列值是否小于或等于输入值。 |
| not equal | 判断列值是否不等于输入值。 |
| like | 模糊匹配,大小写敏感。例:ToolJet不会匹配tooljet。 |
| ilike | 模糊匹配,大小写不敏感。例:ToolJet会匹配tooljet。 |
| match | 正则匹配,大小写敏感。例:^ToolJet$匹配ToolJet但不匹配ToolJet Inc。 |
| imatch | 正则匹配,大小写不敏感。例:^ToolJet$匹配ToolJet但不匹配ToolJet Inc。 |
| in | 判断列值是否在输入的值列表中。例:(1,2,3)。 |
| is | 判断列值是否等于输入值,用于 boolean 类型。 |
清空过滤器(Clear Filter)
既可以逐个删除过滤器,也可以一键清空全部过滤器。
源码视角:Filter 条件如何变成查询
前端 Filter 组件 维护“列 + 操作符 + 值”三要素齐全的过滤器集合,并通过 usePostgrestQueryBuilder 把它们编译进查询串:
// frontend/src/TooljetDatabase/usePostgrestQueryBuilder.jsx const { column, operator, value } = filters[key]; if (!isEmpty(column) && !isEmpty(operator) && !isEmpty(value)) { postgrestQueryBuilder.current.filterQuery.filter(column, operator, value); }filter/sort/pagination三段查询参数最终拼接成一条请求,经tooljetDatabaseService.findOne(...)发送;而服务端 tooljet-db 控制器中的@All('/proxy/*')代理端点 把请求转发给组织专属的 PostgREST 实例——也就是说,like/ilike/match/imatch等操作符直接对应 PostgREST 的过滤语法,content-range响应头则被用来提取总行数做分页。此外,每次增删改后前端会带着当前的 filter 与 sort 状态重新拉取数据(handleRefetchQuery),保证编辑界面与过滤视图一致。
排序数据(Sort)
点击顶部的Sort按钮,从下拉菜单中选择一个column,再选择ascending(升序)或descending(降序),即可对表数据排序。
从实现看,排序同样由 usePostgrestQueryBuilder 中的sortQuery.order(column, order)生成 PostgREST 的order参数,与过滤条件、分页(limit/offset,重置时默认limit=50, offset=0)合并为同一条查询,因此排序、过滤与分页可以任意叠加且互不覆盖。
小结
Database Editor 把 ToolJet Database 的日常操作收敛到四件事:建表(含四类列约束)、行级读写(新增/整行编辑/单元格编辑/删除)、CSV 批量 Upsert(1000 行、5 MB 默认上限,可经TOOLJET_DB_BULK_UPLOAD_MAX_ROWS与TOOLJET_DB_BULK_UPLOAD_MAX_CSV_FILE_SIZE_MB调整)以及过滤/排序查询。所有操作都有对应的服务端端点与校验逻辑(控制器、批量上传服务),配合 Data Types、Primary Key 与 Foreign Key 文档,可以构成一套完整的、可审计的可视化管理闭环。
【免费下载链接】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),仅供参考