使用foreach行在数据框内捕获和写入字符串

时间:2019-05-29 16:48:01

标签: scala apache-spark hadoop apache-spark-sql

在使用scala替换从数据帧的每一行中从特定字段获得的内容之后,尝试捕获并写入字符串值。但是由于它是部署在群集上的,因此无法捕获任何记录。谁能提供解决方案?

假设TEST_DB.finalresult具有2个字段input1和input2:

val finalresult=spark.sql("select * from TEST_DB.finalresult")

finalResult.foreach { row => 
    val param1=row.getAs("input1").asInstanceOf[String]
    val param2=row.getAs("input2").asInstanceOf[String]

    val string = """new values of param1 and param2 are -> """ + param1 + """,""" + param2
    // how to append modified string to csv file continously for each microbatch in hdfs ??
}

1 个答案:

答案 0 :(得分:3)

在代码中,您创建了所需的string变量,但是该变量没有保存在任何地方,因此看不到结果。

您可以在每个foreach执行中打开所需的csv文件并附加新的字符串,但是我想提出一个不同的解决方案。

如果可以的话,请尝试始终使用Spark的内置功能,因为(通常)它是经过优化的,并且在处理空输入方面更好。您可以通过以下方式实现相同目的:

import org.apache.spark.sql.functions.{lit, concat, col}

val modifiedFinalResult = finalResult.select(
 concat(
  lit("new values of param1 and param2 are -> "),
  col("input1"),
  lit(","),
  col("input2")
 ).alias("string")
)

在变量modifiedFinalResult中,将有一个火花数据框,其中包含名为string的单列,该列表示与代码中的变量string完全相同的输出。之后,您可以将数据框直接保存为单个csv文件(使用重新分区功能):

modifiedFinalResult.repartition(1).write.format("csv").save("path/to/your/csv/output")

PS:这也是对未来的建议,请尝试避免在数据类型之后命名变量。