NocoBase 数据可视化 SQL 模式:编写查询语句获取图表数据完整指南
2026/9/15 15:25:27 网站建设 项目流程

NocoBase 数据可视化 SQL 模式:编写查询语句获取图表数据完整指南

【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase

NocoBase 数据可视化模块的"数据查询"面板提供了 SQL 模式,允许开发者直接编写原生 SQL 查询语句(支持多表 JOIN、VIEW 等完整 SQL 语法)来获取图表数据,并支持字段映射、上下文变量、Table/JSON 结果预览与保存回滚。本文以 sql-data-query.md 为骨架,结合plugin-data-visualization插件源码,完整讲解从编写 SQL、运行查询、查看结果到图表映射的全流程,并深入剖析查询动作在服务端的真实执行链路。

一、SQL 模式的定位与入口

在数据可视化页面中,进入图表配置后打开"数据查询"面板,即可在面板中切换到SQL 模式。与基于数据表字段的图形化查询模式不同,SQL 模式将查询能力完全交给 SQL 语句本身:

  • 在"数据查询"面板选择"SQL"模式;
  • 输入 SQL 语句后,点击"运行查询"执行;
  • 查询返回的结果集可直接用于后续的图表映射与渲染。

SQL 模式的适用场景非常明确:当图形化查询难以表达复杂的统计逻辑时(例如多表关联聚合、窗口函数、子查询、视图查询等),SQL 模式提供了完整的表达能力,真正做到"直接用返回结果进行图表映射与渲染"。

底层支持:CodeMirror SQL 编辑器

从源码实现看,SQL 编辑器的输入能力由 CodeMirror 的 SQL 语言支持提供。在 CodeEditor.tsx 中可以看到:

sql: () => import('@codemirror/lang-sql').then((m) => m.sql()),

编辑器按模式动态加载@codemirror/lang-sql,为 SQL 编写提供语法高亮等基础编辑体验。

二、编写 SQL 语句与运行查询

SQL 模式支持复杂的多表 JOIN、VIEW 等完整 SQL 语句,不局限于单表简单查询。

示例:按月统计订单金额

以订单表order为例,按月份聚合订单总金额:

SELECT TO_CHAR(order_date, 'YYYY-MM') as mon, SUM(total_amount) AS total FROM "order" GROUP BY mon ORDER BY mon ASC LIMIT 100;

要点说明:

  • TO_CHAR(order_date, 'YYYY-MM')将日期格式化为YYYY-MM的月份字符串;
  • SUM(total_amount)对订单金额求和;
  • GROUP BY mon按月分组,ORDER BY mon ASC按月份升序排列;
  • LIMIT 100限制返回行数,在调试阶段可显著减少数据传输量、加快预览速度。

注意:示例中使用了 PostgreSQL 的TO_CHAR函数。若你的数据源是 MySQL、SQLite 等其它数据库,需要替换为对应方言的日期格式化函数(如 MySQL 的DATE_FORMAT)。SQL 语句最终会直接提交到目标数据源的数据库执行,因此请以所选数据源的 SQL 方言为准。

数据源选择

从 DaraButton.tsx 与 ChartBlockModel.tsx 的源码可以看到,SQL 模式会记录sqlDatasource作为当前查询的数据源标识:

const dsKey = query?.sqlDatasource || DEFAULT_DATA_SOURCE_KEY;

即:SQL 查询始终绑定到某个具体数据源(默认主数据源),服务端在执行时通过dataSource参数定位数据库实例。这意味着你可以针对不同的数据源分别编写 SQL,并在同一图表配置中切换数据源后重新运行查询。

三、查看结果:分页与 Table/JSON 预览

编写完 SQL 并点击"运行查询"后,点击"查看数据"按钮即可打开数据结果预览面板。结果预览支持:

  • 分页展示:查询结果按页浏览,避免一次性渲染大量数据拖慢界面;
  • Table/JSON 切换:可以在表格视图与 JSON 视图之间切换,用于检查列名与数据类型。

Table 视图便于直观浏览数据;JSON 视图则能看清每列的精确字段名、值类型(字符串、数字、布尔、对象等),这对下一步"字段映射"尤其重要——字段名不一致是图表配置报错的常见原因。

四、字段映射:维度列在前、度量列在后

查询结果本身只是一份数据,要让图表正确渲染,需要在图表选项配置中基于查询结果的列完成映射,告诉图表哪一列是 X 轴(维度/分类),哪一列是 Y 轴(度量/值)。

默认映射规则

系统默认的自动映射规则是:

  • 第一列作为维度(x 轴 或 分类);
  • 第二列作为度量(y 轴 或 值)。

因此,SQL 中字段的顺序至关重要。请把维度字段放在第一列,度量字段放在后面:

SELECT TO_CHAR(order_date, 'YYYY-MM') as mon, -- 维度字段 放在第一列 SUM(total_amount) AS total -- 度量字段 放在后面

从 ChartBlockModel.tsx 的实现可以看出,SQL 模式在保存/构建图表模型时会从查询数据结果解析字段列表(fields),这一行为印证了"查询结果列"是字段映射的唯一数据来源:

if (query?.mode === 'sql') { // sql 模式:从查询数据结果解析 fields }

所以当你修改了 SQL 的 SELECT 列、导致返回字段变化后,重新运行查询并让字段列表刷新,再进行图表映射,就能避免因旧字段名失效而产生的报错。

五、使用上下文变量:让 SQL 感知当前用户与时间

SQL 模式支持在语句中引用上下文变量,使查询结果随当前登录用户、当前时间等上下文动态变化。

插入方式

  1. 点击 SQL 编辑器右上角的x 按钮,打开上下文变量选择器;
  2. 从变量列表中选择需要的变量;
  3. 确认后,变量表达式会被插入到 SQL 文本的光标位置(若先选中了文本,则插入到选中内容的位置,替换选中区域)。

变量写法示例

以当前用户创建时间为例,插入后的表达式为:

{{ ctx.user.createdAt }}

特别提醒:不要自己另外加引号。例如不要写成'{{ ctx.user.createdAt }}',因为变量会被 NocoBase 在服务端按模板表达式解析替换为实际值,多出的引号会导致替换结果被包在字符串字面量中,从而产生错误的 SQL 语义。

服务端如何解析变量

在服务端查询动作中,变量解析由 actions/query.ts 的parseVariables中间件负责。该中间件会先判断查询模式:

  • mode === 'sql'时,保持 SQL 文本不变(ctx.action.params.values = { mode, ...values }),随后通过middlewares.parseVariables解析filter等参数中的上下文变量;
  • 非 SQL 模式(builder 等)则走flow-engineresolveFlowModelVariablesTemplate流程解析模板。

也就是说,SQL 文本中{{ ctx.xxx }}形式表达式的最终求值发生在服务端查询执行前,替换后的语句才是真正提交到数据库执行的 SQL。

六、服务端查询执行链路:charts.queryData 动作剖析

深入源码可以发现,SQL 模式的"运行查询"最终调用的是charts资源的queryData动作。在 server/plugin.ts 中注册如下:

this.app.resourceManager.define({ name: 'charts', actions: { queryData: queryDataAction, }, }); this.app.acl.allow('charts', 'queryData', 'loggedIn');

而 actions/query.ts 中的queryDataAction通过 koa-compose 串联了四个中间件,形成完整的执行链路:

await compose([checkPermission, parseVariables, cacheMiddleware, queryData])(ctx, next);

各中间件职责如下:

中间件职责
checkPermission数据查询权限校验,基于 ACL 对目标数据源与集合执行查询权限检查;root角色直接放行,无权限时抛出NoPermissionError并返回 403
parseVariables解析查询参数中的上下文变量(SQL 模式保持 SQL 文本,非 SQL 模式走 flow-engine 模板解析)
cacheMiddleware查询结果缓存:当配置了cache.enabled且存在uid时,以[uid, query]为缓存键读写缓存,refresh可强制刷新,ttl控制有效期
queryData真正的数据查询:通过数据源管理定位数据库,调用repository.query({ context, ...queryOptions, timezone })执行查询并返回结果

其中queryData通过getQueryDatabase根据dataSource参数从app.dataSourceManager.dataSources中取出对应数据源的数据库实例(未指定时回退到ctx.db主库),并透传x-timezone请求头作为时区参数,保证时间字段的转换与当前用户时区一致。parseVariables中针对mode !== 'sql'legacy-schema兼容逻辑与flow-engine的模板安全校验,也印证了不同查询模式在变量处理上的差异。

相关的权限校验与变量解析逻辑在 query.test.ts 中有对应的测试覆盖,可作为理解上述链路的参考。

七、实战建议

根据官方文档与源码实现,在实际使用 SQL 模式时有几点建议:

  1. 列名稳定后再进行图表映射:图表配置保存的是字段名与图表维度的映射关系,若后期修改 SQL 导致列名变化,已保存的映射会因找不到字段而报错。建议在 SQL 确定、列名稳定之后再完成图表映射。
  2. 调试阶段设置LIMITLIMIT 100之类的限制能减少返回行数,加快预览响应速度;确认无误后再移除或调整限制。
  3. 注意字段顺序:默认第一列作为维度、第二列作为度量,编写 SELECT 时先排维度列、后排度量列,可避免手动调整映射的麻烦。
  4. 上下文变量不要加引号{{ ctx.user.createdAt }}直接写在 SQL 中,由服务端替换为实际值。
  5. 多数据源场景确认数据源:SQL 模式绑定sqlDatasource,请确认查询面板选中的数据源与 SQL 方言一致。

八、预览、保存与回滚

SQL 模式的编辑状态管理遵循"运行预览、保存落库、取消回滚"的闭环:

  • 运行查询:点击"运行查询"会执行请求数据(走上述charts.queryData链路),并刷新图表预览,让你实时看到当前 SQL 对应的图表效果;
  • 保存:点击"保存"会将当前 SQL 文本等配置保存到数据库,成为该图表的正式配置;
  • 取消:点击"取消"回到上次保存的状态,丢弃当前未保存的变更。

这一机制意味着你可以放心地反复调整 SQL 进行试错:只要不点"保存",任何改动都可以通过"取消"一键回退;只有明确点击保存后,SQL 与字段映射等配置才会持久化。

总结

SQL 模式是 NocoBase 数据可视化中面向复杂查询场景的利器:它以原生 SQL 提供完整的查询表达能力(多表 JOIN、VIEW、聚合、子查询等),配合上下文变量实现"千人千面"的动态查询,再通过字段映射将结果列绑定到图表的维度与度量上。理解其背后的服务端执行链路(权限校验 → 变量解析 → 缓存 → 查询)与"第一列维度、第二列度量"的默认映射规则,能帮助你更高效、更稳妥地完成复杂图表的搭建。

【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase

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

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

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

立即咨询