You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Databricks代码打包Scala jar时dbutils.fs.ls().toDF()报错如何解决

问题原因分析
  • 第一个报错:Databricks 交互式 Notebook 环境默认内置了FileInfo序列转 DataFrame 的隐式转换规则,但本地编译打包 Scala Jar 时没有引入对应隐式逻辑,因此Seq[FileInfo]没有toDF方法。
  • 第二个报错:一是你定义的 schema 是ArrayType,但createDataFrame方法接收的单表结构是StructType;二是你传入的 RDD 元素是FileInfo类型,而带 schema 参数的createDataFrame要求 RDD 元素必须是Row类型,因此重载方法匹配失败。

正确实现方案

前置依赖配置

打包前先在构建配置中引入 dbutils 依赖,scope 设为 provided(Databricks 集群已自带该依赖,无需打入 Jar 避免冲突),以 sbt 配置为例:

libraryDependencies += "com.databricks" % "dbutils-api_2.12" % "0.0.6" % Provided

版本需和你使用的 Scala 版本、Databricks 运行时版本匹配。


方案1:样例类转换(最简便)

借助样例类和spark.implicits的内置隐式转换直接生成 DF,无需手动定义 schema:

import org.apache.spark.sql.SparkSession
import com.databricks.dbutils_v1.DBUtilsHolder.dbutils

// 定义和FileInfo字段对应的样例类,注意size用Long类型避免大文件溢出
case class FileItem(path: String, name: String, size: Long)

object DbutilsLsDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession
      .builder()
      .appName("myApp")
      .enableHiveSupport()
      .getOrCreate()
    // 必须导入spark隐式转换
    import spark.implicits._

    val folderPath = "abfss://container@storage.dfs.core.windows.net"
    // 将FileInfo序列映射为样例类序列后直接调用toDF
    val fileDF = dbutils.fs.ls(folderPath).map(f => FileItem(f.path, f.name, f.size)).toDF()

    fileDF.show()
    spark.stop()
  }
}

方案2:手动转Row+自定义Schema

如果不想定义样例类,可以手动转换为Row并指定Schema:

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{StructType, StructField, StringType, LongType}
import com.databricks.dbutils_v1.DBUtilsHolder.dbutils

object DbutilsLsDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession
      .builder()
      .appName("myApp")
      .enableHiveSupport()
      .getOrCreate()

    // 定义正确的StructType格式表结构,不要用ArrayType
    val schema = StructType(Seq(
      StructField("path", StringType, nullable = true),
      StructField("name", StringType, nullable = true),
      StructField("size", LongType, nullable = true)
    ))

    val folderPath = "abfss://container@storage.dfs.core.windows.net"
    val fileInfos = dbutils.fs.ls(folderPath)
    // 先把FileInfo转为Row再并行化
    val rowRDD = spark.sparkContext.parallelize(fileInfos.map(f => Row(f.path, f.name, f.size)))
    val fileDF = spark.createDataFrame(rowRDD, schema)

    fileDF.show()
    spark.stop()
  }
}

注意事项
  • 如果本地测试运行,需要提前配置对应存储服务的访问权限(比如ADLS需要配置访问密钥、SAS令牌等)
  • 文件大小字段必须用Long类型,不要用Int,避免超出Int取值范围导致溢出

内容的提问来源于stack exchange,提问作者steven hurwitt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:54:04