Scala与Spark代码返回类型不匹配编译错误及数组返回实现咨询
让我来逐个帮你解决这两个Spark Scala的问题:
问题1:return语句处的编译错误分析与修复
错误原因
你的代码里,res被赋值为spark.read.format("jdbc").jdbc(...).registerTempTable("")的执行结果,但registerTempTable是一个仅做副作用的方法——它的作用是把DataFrame注册成临时表,返回类型是Unit(没有返回值)。而你的函数getData声明要返回Dataset[Row],这就导致了类型不匹配:编译器发现你试图返回Unit,但它需要的是Dataset[Row],所以抛出了编译错误。
修复代码
你需要把读取JDBC数据和注册临时表的操作分开,让res指向真正的Dataset[Row]实例,再单独执行注册操作:
def getData(queries: Array[String]): Dataset[Row] = { val res = spark.read.format("jdbc").jdbc(jdbcUrl, "", props) res.registerTempTable("valid_table_name") // 建议给临时表起个有意义的名字,空字符串可能引发其他问题 res // Scala会把函数最后一行作为返回值,可省略return }
问题2:返回Array[Dataset[Row]]的代码调整
现有代码的问题
当前的getDataFrames函数默认返回Unit,因为它最后一行是变量赋值操作,没有显式返回jdbcResult这个数组。另外你提到Spark 2.0.0中DataFrame无法作为依赖使用——其实不用纠结,Spark 2.0里DataFrame就是Dataset[Row]的类型别名,直接返回Array[Dataset[Row]]完全符合你的需求。
修正后的可行代码
你只需要在函数最后显式返回jdbcResult,或者直接把map的执行结果作为函数最后一行(Scala会自动将最后一行作为返回值)。另外可以优化代码结构,让逻辑更清晰:
def getDataFrames(queries: Array[String]): Array[Dataset[Row]] = { queries.map(query => { val tablename = extractTableName(query) // 根据表名选择对应的JDBC地址 val targetJdbcUrl = if (tablename.contains("1")) jdbcUrl1 else jdbcUrl2 // Spark 2.0推荐用spark.read替代spark.sqlContext.read,功能一致 spark.read.format("jdbc").jdbc(targetJdbcUrl, query, props) }) }
注意:要确保extractTableName方法能正确提取表名,且jdbcUrl1、jdbcUrl2、props这些变量在当前函数作用域内是可访问的。
内容的提问来源于stack exchange,提问作者Devas
相关产品推荐
相关产品推荐

