TblSqlSource.execute_query() returns lazy tbl objects that fail ellmer serialization with Spark/Databricks connections

未关闭
#198 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
68/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
r, sql
领域
backend, databases

调研方向

阅读 TblSqlSource.R 中的 execute_query() 和 querychat_tool_result(),并将它们与已经返回收集数据的 test_query() 进行比较。使用 Databricks 复现来跟踪工具结果的序列化路径。完成的标准是:来自 lazy tbl_sql 源的 update_dashboard 结果可以在不触发 nrow() 失败的情况下进行序列化,同时现有的 dashboard 行为保持不变。

由索引模型根据 Issue 内容生成。

描述

When using querychat with a Databricks (Spark SQL) connection via dbplyr::tbl(), the execute_query() method in TblSqlSource returns a lazy tbl_sql object. When ellmer tries to serialize this tool result to JSON, it fails because jsonlite::toJSON() calls nrow() on the lazy table, which returns NA for remote connections.

Error Message
Error in tool_string() at ellmer/R/provider-aws.R:
! Could not convert tool result from a  object to JSON.
ℹ If you are the tool author, update the tool to convert the result to a string or JSON.
Caused by error in if (!nrow(x)) ...:
! missing value where TRUE/FALSE needed
Reproduction
library(querychat)
library(DBI)
library(odbc)
library(dbplyr)

con <- dbConnect(odbc(), dsn = "Databricks_DSN")
tbl_obj <- tbl(con, in_catalog("catalog", "schema", "table_name"))

qc <- QueryChat$new(
  tbl_obj,
  client = chat_openai()  # or any ellmer chat client
)

When the LLM invokes the update_dashboard tool, the error occurs

Root Cause

In TblSqlSource.R, execute_query() returns a lazy tbl:

execute_query = function(query) {
  sql_query <- self$prep_query(query)
  dplyr::tbl(private$conn, dplyr::sql(sql_query))  # Returns lazy tbl
}

This works for the Shiny dashboard (which calls collect() before rendering), but fails when ellmer tries to serialize the tool result for the LLM.

Note: test_query() works correctly because it delegates to DBISource which returns collected data.

Attempted Workarounds

  1. Using DBISource directly - Passing the DBI connection + table name doesn't work with Databricks three-part naming (catalog.schema.table) due to table name validation.
  2. Custom DataSource subclass - Creating a subclass that overrides execute_query() to collect results hits the same table name validation issue.
  3. Registering S3 methods for jsonlite::toJSON - The method dispatch doesn't seem to pick up custom methods for tbl_sql classes.

Suggested Fix

One of:

  1. Collect in execute_query() for TblSqlSource:
    execute_query = function(query) {
    sql_query <- self$prep_query(query)
    dplyr::collect(dplyr::tbl(private$conn, dplyr::sql(sql_query)))
    }
  2. Add a parameter to control whether results are collected (for users who need lazy evaluation).
  3. Handle serialization in querychat_tool_result() by collecting lazy tbls before returning.

Environment

  • querychat: (version)
  • ellmer: (version)
  • R: (version)
  • Database: Databricks (Spark SQL) via odbc
  • OS: Linux
主要语言
Python
星标
213
派生
32
平均合并
1 天 19 小时
30 天内合并 PR
8

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

posit-dev/querychat 的其他 Issue

查看 posit-dev/querychat 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。