ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MCP Toolbox Looker 集成实战:looker-query-sql 工具生成语义模型驱动 SQL

MCP Toolbox Looker 集成实战:looker-query-sql 工具生成语义模型驱动 SQL MCP Toolbox Looker 集成实战looker-query-sql 工具生成语义模型驱动 SQL【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolboxlooker-query-sql是 MCP Toolbox 中 Looker 集成套件提供的工具之一它基于 Looker 语义模型LookML model/explore生成一段可执行的 SQL 查询并返回原始 SQL 文本而不是查询结果。本文以 looker-query-sql 官方文档 为主体结合仓库源码深入讲解该工具的十个参数、YAML 配置方法、底层调用链以及与looker-query工具的分工帮助读者理解 Looker 如何把一次查询请求翻译成数据库 SQL并掌握在 MCP Toolbox 中配置、调试和审计该工具的方法。工具定位查询 SQL 而非查询结果Looker 的核心能力之一是基于语义层semantic layer构建查询用户在 LookML 模型中定义 model、explore、dimension、measure 等元数据Looker 根据这些元数据把用户请求翻译为针对底层数据库的 SQL。looker-query-sql正是把这一翻译结果暴露出来的工具——它向 Looker API 提交一个内联查询inline query并请求以sql格式返回因此其输出是 Looker 实际会针对数据库执行的那段 SQL 文本。这一能力在以下场景中非常实用排查 Looker 生成的 SQL 是否符合预期例如聚合层级、时区处理、JOIN 顺序为 LLM/Agent 提供可执行的 SQL 样例辅助理解 LookML 模型语义审计查询下推行为确认过滤条件、动态字段如何被翻译成 SQL。从源码看该工具与looker-query是姊妹工具两者共享几乎完全相同的参数处理逻辑唯一的关键区别在于请求的result_format——looker-query请求json格式并解析为结果数组见 lookerquery.go而looker-query-sql请求sql格式并原样返回原始 SQL 字符串见 lookerquerysql.go。用官方文档的话说该工具输出的是原始 SQL 文本The result of this tool is the raw SQL text。十个参数与 looker-query 完全一致looker-query-sql共接受十个参数其中model、explore、fields为必填其余均为可选。这些参数在源码中统一定义于 lookercommon.GetQueryParameters()looker-query-sql与looker-query均通过该函数构建参数清单并在Initialize阶段注入工具 Manifest见 lookerquerysql.go。参数类型必填说明modelstring是包含 explore 的 LookML model 名称可从get_models工具获取explorestring是要被查询的 explore 名称可从get_explores工具获取fieldsstring[]是查询要返回的字段列表元素为 dimension、measure、filter 或 parameter 的字段名filtersmap否过滤条件集合键为完整限定的view.field字段名值为 Looker 过滤表达式默认空 mappivotsstring[]否数据透视字段列表这些字段也必须同时出现在fields中默认空数组sortsstring[]否排序字段列表可含方向如[view.field desc]默认空数组limitint否行数上限默认 500传-1表示不限tzstring否查询时区如America/Los_Angeles缺省时使用运行时本地时区filter_expressionstring否自定义 Looker 表达式过滤串即 custom filter支持复杂逻辑与字段间比较dynamic_fieldsobject[]否动态字段数组table calculation、自定义 measure、自定义 dimension以 JSON 对象形式定义默认空数组必填三参数model、explore、fields三个必填参数共同定位查什么。model与explore分别对应 LookML 模型和其中的 explore 视图fields则决定要检索哪些字段。从 ProcessQueryArgs 的实现可以看到参数最终被组装成 Looker SDK 的v4.WriteQuery结构wq : v4.WriteQuery{ Model: paramsMap[model].(string), View: paramsMap[explore].(string), Fields: fields, Pivots: pivots, Filters: filters, Sorts: sorts, QueryTimezone: tz, Limit: limit, FilterExpression: filterExpressionPtr, DynamicFields: dynamicFieldsPtr, }注意explore参数被映射到WriteQuery.View字段——这是 Looker API 的惯用对应关系在排查问题时值得留意。filters过滤表达式的书写规范filters是一个 map官方文档与源码对值的书写规范有明确约束详见 looker-query.md 与 lookercommon.go每个键必须是完整限定的view_name.field_name且应逐字复制自get_dimensions、get_measures、get_filters或get_parameters的返回结果view 前缀和点号不可省略值应裸传bare不要额外包一层引号字符对于 LookMLparameter字段使用原始allowed_value如first_touch而不是first_touch使用not null而不是-NULL值中包含逗号时必须用单引号包裹如New York, NY对 suggestible 字段可用get_field_value_suggestions工具获取合法过滤值。一个典型示例filters: {view_name.field_name: value, view_name.date: 7 days}源码层面还有一个值得了解的细节在 ProcessQueryArgs 中工具会剥除键和字符串值上的单层包裹引号key 和 value 首尾都是或时去掉以保证type: unquoted参数的值能够裸值代入 SQL。随后EscapeUnquotedParameterFilters 会查询 explore 的参数元数据对指向type: unquoted参数的过滤值做转义——Looker 把_视为单字符通配符、%视为多字符通配符未转义的值如first_touch会被解释成通配模式并触发 400 错误转义逻辑通过^前缀对元字符逐 rune 处理见 escapeUnquotedParameterValue。该步骤是尽力而为若元数据查询失败例如调用方缺少 explore 读取权限工具会记录警告并继续保证非参数过滤的查询不受影响。filter_expression字段级复杂表达式filter_expression提供比filters更灵活的表达式过滤能力支持在表达式内引用字段、组合逻辑并调用 Looker 函数详见 looker-query.md使用${view.field_name}语法引用字段支持逻辑运算符AND、OR、NOT与比较运算符支持 Looker 函数如matches_filter、now、add_days、diff_days。官方示例${orders.order_date} add_years(-1, now()) ${activity.email} ! ${activity_drive_facts.current_owner_email} matches_filter(${order.order_month}, 24 months) AND matches_filter(${order.order_month}, before 2024/07/01)在源码中该参数被转换为WriteQuery.FilterExpression指针字段只有提供且为非空字符串时才赋值见 lookercommon.go。dynamic_fields临时计算字段dynamic_fields用于定义 LookML 模型中不存在的临时计算字段table calculation、自定义 dimension、自定义 measure以 JSON 对象数组形式传入其中同样支持${view.field_name}引用语法。官方文档给出的三类示例详见 looker-query.mdTable Calculation[{table_calculation: test, label: test, expression: ${order_items.total_sale_price} * 0.8, _type_hint: number}]Custom Dimension[{dimension: days_since_order, label: days since order, expression: diff_days(${order.order_date}, now()), _type_hint: number}]Custom Measure[{measure: sum_of_revenue, label: Sum of Revenue, based_on: training.revenue, type: sum, _type_hint: number}]源码中该参数先被解析为[]any仅当非空时通过json.Marshal序列化为 JSON 字符串再赋给WriteQuery.DynamicFields见 lookercommon.go。pivots、sorts、limit、tzpivots透视字段列表源码要求其元素必须同时包含在fields中见 lookercommon.gosorts排序字段列表可带方向后缀如[field.id desc 0]见 lookercommon.golimit行数上限默认 500WithIntDefault(500)-1表示不限制见 lookercommon.gotz查询时区。缺省时源码会尝试获取运行时本地时区tzlocal.RuntimeTZ()失败则回退到Etc/UTC见 lookercommon.go。这意味着同一查询在不同部署环境下可能因默认时区不同而产生不同 SQL生产环境建议显式传入tz。YAML 配置示例与 MCP Toolbox 中其他工具一致looker-query-sql通过工具配置文件YAML声明。完整的配置骨架如下对应 looker-query-sql.mdkind: tool name: query_sql type: looker-query-sql source: looker-source description: | This tool generates the underlying SQL query that Looker would execute against the database for a given set of parameters. It is useful for understanding how Looker translates a request into SQL. Parameters: All parameters for this tool are identical to those of the query tool. This includes model_name, explore_name, fields (required), and optional parameters like pivots, filters, filter_expression, dynamic_fields, sorts, limit, and query_timezone. Output: The result of this tool is the raw SQL text.该 YAML 在仓库的预置配置 internal/prebuiltconfigs/tools/looker.yaml 中以query_sql为名出现source指向预置的looker-source。配置字段参考表looker-query-sql工具配置仅包含三个顶层字段见 lookerquerysql.go 与文档 Reference 表字段类型必填说明typestring是必须为looker-query-sqlsourcestring是该 SQL 将在其上执行/生成的 source 名称必须引用一个兼容的 Looker sourcedescriptionstring是传递给 LLM 的工具描述文本其中description在Initialize阶段被强制校验为空会直接报错description is required for tool %q见 lookerquerysql.go因此它虽然是给 LLM 看的文本但在配置层面是硬性必填项。type和source还带有validate:required校验标签。工具注册通过全局tools.Register(resourceType, newConfig)完成见 lookerquerysql.go若重复注册会 panic。配置解析的严格性由 lookerquerysql_test.go 中的负向用例佐证在配置中写入未知字段method会触发unknown field method解析错误。底层调用链从参数到 SQL 文本结合 lookerquerysql.go一次完整的调用经历了以下步骤校验 source 兼容性Invoke首先将传入的 source 断言为compatibleSource接口要求实现UseClientAuthorization、GetAuthTokenHeaderName、LookerApiSettings、GetLookerSDK四个方法不兼容则返回客户端错误解析查询参数调用lookercommon.ProcessQueryArgs把十个参数组装为v4.WriteQuery结构获取 Looker SDK 实例通过source.GetLookerSDK(ctx, accessToken)创建 SDK 客户端转义 unquoted 参数过滤值调用lookercommon.EscapeUnquotedParameterFilters失败仅告警不中断提交内联查询并以 sql 格式返回调用lookercommon.RunInlineQuery(ctx, sdk, wq, sql, ...)得到原始 SQL 文本。值得关注的是第 5 步的 RunInlineQuery 实现它优先调用新的 API 端点/4.0/queries/run_inline通过POST携带query、render_options与query_api_client_context并附带一个名为MCP Toolbox的QueryApiClientContext如果新端点失败则回退到 SDK 标准的RunInlineQuery。这一客户端名称正是 System Activity 审计能力的关键见下文。相比之下looker-query在同样的调用链中以json为格式参数并把响应 JSON 反序列化为[]any返回见 lookerquery.golooker-query-sql则直接把字符串响应作为结果返回。另外该工具默认继承只读注解tools.NewReadOnlyAnnotations见 lookerquerysql.go从工具语义上它只读语义模型、不修改任何数据。兼容的 SourceLooker Source 前提条件looker-query-sql必须搭配 Looker source 使用。source 在 source.md 中定义关键前提包括Looker API 用户该 source 仅使用 API 认证需要先创建 API 用户base_url形如https://looker.example.com不要带结尾/本地部署有时需附加 API 端口如https://looker.example.com:19999client_id / client_secret由 Looker 服务器分配若使用 Looker OAuth 则无需配置verify_ssl几乎总是应为true小写除非使用自签名证书timeout查询执行最大等待时间如600suse_client_oauth是否透传客户端 OAuth access token。一个最小可用的 source 配置示例摘自 source.mdkind: source name: my-looker-source type: looker base_url: ${LOOKER_BASE_URL} client_id: ${LOOKER_CLIENT_ID:} client_secret: ${LOOKER_CLIENT_SECRET:} verify_ssl: ${LOOKER_VERIFY_SSL:true} timeout: 600s use_client_oauth: ${LOOKER_USE_CLIENT_OAUTH:false} show_hidden_models: ${LOOKER_SHOW_HIDDEN_MODELS:true} show_hidden_explores: ${LOOKER_SHOW_HIDDEN_EXPLORES:true} show_hidden_fields: ${LOOKER_SHOW_HIDDEN_FIELDS:true}若配置中的source指向的类型不兼容ValidateSource会抛出invalid source for looker-query-sql tool错误见 lookerquerysql.go因此 source 类型务必为looker。在 Looker System Activity 中识别 MCP Toolbox 查询自 Looker v25.18 起MCP Toolbox 发起的查询可以在 Looker 的 System Activity 中被识别在 History explore 中使用API Client Name字段即可定位到 MCP Toolbox 的查询。这一能力在实现层面有迹可循RunInlineQuery构造的新端点请求中携带了QueryApiClientContext{Name: MCP Toolbox}见 lookercommon.goLooker 将该名称记录为查询的 API 客户端标识。这意味着你可以在 System Activity 中按 API Client Name 过滤审计哪些 model/explore 被 Agent 生成的 SQL 查询过、耗时与资源占用如何为 BI 平台的安全审计与成本治理提供依据。与其他 Looker 工具的配合looker-query-sql通常与 Looker 工具套件中的发现类工具配合使用形成完整的查询工作流用 looker-get-models 获取可用 model用looker-get-explores获取 explore用looker-get-dimensions、looker-get-measures、looker-get-filters、looker-get-parameters获取合法字段文档明确提示使用这些工具查找有效字段用looker-query-sql先验证 SQL 翻译结果再决定是否用looker-query实际执行并取回 JSON 结果。这一先生成 SQL 审阅、再执行取数的模式尤其适合对 Looker SQL 生成逻辑有严格要求的分析场景。小结looker-query-sql是 MCP Toolbox Looker 集成中用于获取语义模型翻译后 SQL的只读工具。它与looker-query共享十个参数的完整定义model、explore、fields必填filters、filter_expression、dynamic_fields、pivots、sorts、limit、tz可选唯一的差异是请求结果格式前者返回原始 SQL 文本后者返回 JSON 结果。从源码看其调用链经历了参数组装为WriteQuery、unquoted 参数过滤值转义、内联查询提交携带MCP Toolbox客户端标识等关键步骤为排查 SQL 生成、理解语义模型翻译逻辑和基于 System Activity 的审计提供了完整闭环。【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表