ToolJet Database 表操作实战指南:搜索、重命名、列管理与 Schema 导出的完整解析
【免费下载链接】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 3.0.0-LTS 官方文档 Table Operations 编写,系统讲解 ToolJet Database(内部数据库)中表级与列级操作的完整用法:搜索表、重命名表、新增/编辑/删除列、导出 Schema 以及删除表的确认机制。文章同时深入 后端表操作服务 与 REST 控制器 的真实实现,说明每项操作在双数据库事务下的底层行为、保护性校验与 PostgREST 同步机制,帮助你既会用界面,也能看懂其工程实现。
一、ToolJet Database 表操作总览
ToolJet Database 是内置于 ToolJet 工作区(Workspace)的关系型数据库。每个组织在 PostgreSQL 中拥有独立租户 Schema(从源码结构看,Schema 名为workspace_${organizationId},对应数据库角色为user_${organizationId},见 租户 Schema 初始化),表元数据则记录在应用库的internal_tables表中。
官方文档覆盖了以下七类表操作,全部通过表列表行右侧的 kebab 菜单(三个竖点)或列头操作触发,前端菜单项定义见 表项操作弹出菜单:
| 操作 | 入口 | 对应后端 Action |
|---|---|---|
| Search Table(搜索表) | 工具栏 Search 按钮 | view_tables/view_table |
| Rename Table(重命名表) | kebab 菜单 → Edit table | edit_table |
| Add New Column(新增列) | kebab 菜单 → Add new column,或列头行末的+按钮 | add_column |
| Export Schema(导出结构) | kebab 菜单 → Export | 前端本地导出 |
| Delete Table(删除表) | kebab 菜单 → Delete | drop_table |
| Edit Column(编辑列) | 列名 kebab 菜单 → Edit column | edit_column |
| Delete Column(删除列) | 列名 kebab 菜单 → Delete | drop_column |
后端将上述操作统一注册在一个动作分发表中(见 getActionHandler),每个动作都有独立的 REST 端点,全部挂载在tooljet-db控制器下(见 控制器):
| HTTP 方法与路径 | 动作 |
|---|---|
GET /organizations/:organizationId/tables | 列出表(搜索的数据来源) |
GET /organizations/:organizationId/table/:tableName | 查看单表结构(列、外键、配置) |
PATCH /organizations/:organizationId/table/:tableName | 重命名表/编辑表 |
DELETE /organizations/:organizationId/table/:tableName | 删除表 |
POST /organizations/:organizationId/table/:tableName/column | 新增列 |
PATCH /organizations/:organizationId/table/:tableName/column | 编辑列 |
DELETE /organizations/:organizationId/table/:tableName/column/:columnName | 删除列 |
二、Search Table:搜索表
点击工具栏的Search按钮打开搜索框,输入表名即可在当前组织的表列表中过滤出目标表。该列表数据来自view_tables动作:后端按organizationId查询InternalTable实体,仅返回id与tableName两个字段,并按表名升序排序(见 viewTables 实现)。
需要注意的是:搜索范围严格限定在当前组织内,跨工作区(Organization)不可见;表中记录的是逻辑表名,而物理 PostgreSQL 表名使用的是InternalTable.id,二者通过元数据表映射。
三、Rename Table:重命名表
操作步骤:
- 点击表名右侧的 kebab 菜单图标;
- 选择Edit table,右侧滑出抽屉面板;
- 在面板中修改表名并保存。
后端行为:重命名走edit_table动作,请求体中通过new_table_name字段携带新表名。服务端会先在同一组织内查询是否已存在同名表,若冲突则抛出Table name already exists: <name>错误(见 editTable 中重命名分支)。整个操作在应用库与 ToolJet Database 两个连接上开启事务,任一侧失败都会回滚,保证元数据与物理结构一致。
从源码结构看,edit_table同时承担了列的增删改与重命名职责:前端把“新旧列的对比清单”整体提交,服务端据此批量执行dropColumns/addColumns/changeColumns,因此仅重命名时提交空列变更即可。
四、Add New Column:新增列
两种入口:
- 点击表名右侧 kebab 菜单 →Add new column;
- 点击列头行末的+按钮。
右侧抽屉中需要填写四个要素:
| 字段 | 说明 |
|---|---|
| Column Name | 新列的唯一名称,作为其键标识 |
| Data Type | 从受支持的数据类型中选择合适的类型,详见下文 |
| Default Value | 可选。但当表已有数据行、且列应用了 NOT NULL 约束时,默认值变为必填,否则 PostgreSQL 无法为已有行回填 |
| Foreign Key Relation | 打开开关后弹出菜单,选择外键引用的目标表与目标列 |
支持的数据类型
新增列时可选的数据类型及约束矩阵完整继承自 Data Types 文档:
| Data Type | 说明 | 示例 |
|---|---|---|
| serial | 生成整型序列,常用作主键。新建表时自动创建id列(serial 类型)作为主键 | 1, 2, 3, 4, 5… |
| varchar | 不定长字符串 | 任意字符串 |
| int | 无小数部分的整数 | -2147483648 ~ 2147483647 |
| bigint | 更大的整数 | -9223372036854775808 ~ 9223372036854775807 |
| float | 不精确的变精度数值 | 3.14 |
| boolean | true / false / null | true |
| date with time | ISO 8601 日期时间,底层按 UTC 存储,展示时转换为指定时区 | '2024-07-22 15:30:00' |
| jsonb | 存储 JSON 结构化数据(数组、嵌套对象) | {"name": "John Doe", "age": 30} |
各类型可应用的约束矩阵(Primary Key / Foreign Key / Unique / Not Null):
| Data Type | Primary Key | Foreign Key | Unique | Not Null |
|---|---|---|---|---|
| serial | ✅ | ❌ | ✅ | ✅ |
| varchar | ✅ | ✅ | ✅ | ✅ |
| int | ✅ | ✅ | ✅ | ✅ |
| bigint | ✅ | ✅ | ✅ | ✅ |
| float | ✅ | ✅ | ✅ | ✅ |
| boolean | ❌ | ❌ | ❌ | ✅ |
| date with time | ❌ | ❌ | ❌ | ✅ |
| jsonb | ❌ | ❌ | ❌ | ✅ |
后端实现要点
add_column动作(见 addColumn 实现)做了三件事:
- 元数据登记:为新列生成一个 UUID,写入
InternalTable.configurations.columns.column_names映射(列名 → UUID),该映射用于前端展示与数据行的键名解析; - DDL 执行:通过 TypeORM QueryRunner 调用
addColumn在物理表上建列。其中字符串默认值会经 addQuotesIfString 自动补上单引号(varchar 列的默认值在 PostgreSQL 中需要字面量引号); - 外键校验与创建:若勾选了 Foreign Key Relation,先通过 fetchAndCheckIfValidForeignKeyTables 校验引用表是否存在于本组织;若引用列属于复合主键,则直接拒绝并抛出
Foreign key cannot be created as the referenced column is in the composite primary key.。
所有 DDL 成功后统一执行NOTIFY pgrst, 'reload schema',通知 PostgREST 重新加载表结构,保证应用内数据源立即可查新列。
五、Export Schema:导出表结构
点击表名右侧三个竖点图标 →Export,即可将该表的 Schema 下载为 JSON 文件。需要明确其边界:
- 只导出表结构定义(列名、数据类型、约束等),不包含表内数据,也不包含表间关系(外键引用);
- 在**导出整个应用(App)**时,可以选择导出“带关联表 Schema”或“不带表 Schema”的版本,该选项即基于本 JSON 结构拼装。
前端入口位于 表项操作菜单的 Export schema 项,点击后调用handleExportTable(定义于 TableListItem 组件),基于view_table接口返回的列与配置信息在浏览器侧生成并下载 JSON。
从源码结构看,view_table返回的configurations字段保存了列名到 UUID 的映射以及每列的展示配置(见 viewTable 实现),这正是导出 JSON 的元数据来源。
六、Delete Table:删除表(含引用保护)
操作步骤:点击表名右侧三个竖点 →Delete→ 在确认弹窗中再次点击Delete。
关键保护机制:删除走drop_table动作,服务端在执行前会调用 findQueriesLinkedToTable 检查该表是否被任何应用查询引用——它查询data_queries表,筛选数据源类型为tooljetdb且查询配置(options)中匹配该表 ID 的最新版本记录。若存在引用,直接拒绝删除并返回:
Table can't be deleted, it is being used in app queries
确认无引用后,删除操作在应用库事务(删除internal_tables记录)与TJDB 事务(物理DROP TABLE)中成对执行,任一失败整体回滚(见 dropTable 实现),事务结束后仍会NOTIFY pgrst, 'reload schema'刷新 PostgREST 的表清单。
实践建议:删除表之前,先清理或迁移引用该表的 Data Query,否则删除会被后端直接拦截。
七、Edit Column:编辑列
操作步骤:点击列名上的 kebab 菜单 →Edit column。可修改内容包括列显示名、默认值与约束(如 Not Null、Unique)。
重要限制:编辑列时不能更改数据类型(Data Type)。
后端edit_column动作(见 editColumn 实现)的执行顺序为:
- 更新
InternalTable.configurations中的列配置与列名映射; - 若请求携带
foreign_key_id_to_delete,先dropForeignKey移除旧外键约束; - 通过
changeColumn应用新约束与默认值; - 若列名发生变化(
new_column_name),追加执行renameColumn。
同样的双事务 + 回滚 + PostgREST 重载模式,确保元数据与物理列结构始终一致。
八、Delete Column:删除列
操作步骤:点击列名 kebab 菜单 →Delete。
限制条件:若该列正作为**主键(Primary Key)**使用,则无法删除——必须先移除该列的主键约束(将主键职责转移到其他列),才能删除该列。
后端drop_column动作(见 dropColumn 实现)先从configurations中摘除该列的名称映射与配置,再调用 QueryRunner 的dropColumn执行物理删除,同样在双事务内完成并触发 PostgREST 结构重载。
九、底层机制小结:双库一致性与租户隔离
综合源码可以看到,ToolJet 的每张表操作都遵循同一套工程模式,这也是理解所有表操作行为的钥匙:
- 元数据与物理结构双写:应用库(
InternalTable)记录逻辑表名、列名 → UUID 映射及每列配置;ToolJet Database(租户 Schemaworkspace_<orgId>下的物理表)承载真实数据。所有写操作(建表、改表、增删列)都在两条连接上开事务,失败即双回滚(参考 createTable 事务结构); - PostgREST 感知:每次结构变更后执行
NOTIFY pgrst, 'reload schema',让代理层的数据访问接口即时可见新结构; - 命名安全:字符串默认值自动补引号、jsonb 默认值经
formatJSONB规整、serial 类型识别nextval(前缀(见 prepareColumnListForCreateTable),避免默认值写坏 DDL; - 保护性校验:删表检查应用查询引用、重命名检查同名冲突、外键检查引用表存在性与复合主键引用,均在服务端强制生效,绕过 UI 直接调 API 同样受保护。
掌握了以上界面操作与底层机制,你可以在 ToolJet Database 中安全地完成表结构的全生命周期管理:从建表后的日常增删列、重命名,到跨环境复用结构时的 Schema 导出,再到确认无引用后的彻底删除,每一步都有明确的后端校验作为兜底。
【免费下载链接】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),仅供参考