我的用例是创建一个通用代码,该代码将从文件中读取变量名和路径值,并在spark中创建数据帧。例如...
假设我有一个Path.txt文件,其值如下:
DataSourceName, Path, TempTableName, FinalTableName
IM, Path1, Table_1, Result
ST, Path2, Table_2, Result
RM, Path3, Table_3, Result
现在,我想读取该文件,并使用1st元素创建变量名,2nd元素定义数据文件的路径,3rd元素获取要存储数据的表名。例如:
val RDD= sc.textFile("\path\to\Path.txt").map(rec=> rec.split(","))
for (i <- RDD){
val DF_i(0) = spark.read.option("header","true").csv(i(1))
DF_i(0).registerTempTable("DF_i(2)")
}
val Final = spark.sql("some query on the newly created data frames.This query will also come from a file having all the definitions. But the data frame names will be the one's created in above for loop. This can easily be defined by user manually if they know the data source names coming from Path.txt file ")
Final.saveAsTable("RDD(3)")
例如,读取RDD的第一行后的输出应为:
名称为“ DF_IM
”的数据框。
DF_IM
将在路径“ Path1
”中包含文件数据。
DF_IM
将存储在名为“ Table1
”的临时表中。
整个循环结束后,最终查询的结果将存储在Result
文件第4列中提到的“ Path.txt
”表中。
答案 0 :(得分:-2)
这是有效的代码:
import scala.collection.mutable
import org.apache.spark.sql._
val lines = sc.textFile("/u01/test.csv").map(rec=> rec.split(",")).collect
lines.foreach(line => {
spark.read.option("header","true").csv(line(1)).registerTempTable(line(2))
})
我之前的代码(与您的代码类似)有一个致命错误:在[for(i <-RDD)]循环中,该代码将由执行者执行。执行者无法访问SparkSession变量,因为它无法序列化。正确的方法是将RDD收集到驱动程序,然后在其上循环并使用驱动程序代码一个接一个地创建数据帧。
顺便说一句,您的假设不正确:
我们可以毫无问题地创建mutable.HashMap [String,Dataset [Row]]
i(1)只是一个字符串,我们可以将其放在csv()中。
唯一的问题是在执行程序代码中访问SparkSession变量。就是这样。