如何在使用Spark / Scala读取CSV时捕获每个记录的异常

时间:2018-08-08 02:02:58

标签: scala csv apache-spark exception

我有一个看起来像这样的CSV(无标题):

file_id, file_contents
1001, textString1
1002, textString2
1003, textString3

我正在使用Spark / Scala应用程序读取文件,如下所示:

val df = spark.read
 .text(list: _*)
 .map { r =>
    val str = r.getAs[String]("value")
    val fileId == str.substring(0, str.indexOf(","))
    val fileContents = {
          val content = str.substring(0, str.indexOf(","))
          if (content .startsWith("\"")) content .substring(1, content .length - 1) else content 
          }
          (fileId, fileContents)
      }.toDF("fileId", "fileContents")

当我转换此数据框时,我照常捕获异常并进行处理。但是我的问题是,如果CSV中的不良记录最少,例如内容格式不正确等,则整个文件的应用程序都会失败。我想更改此功能,并确保应用程序标识正确的记录并捕获异常中的不良记录。有人可以帮我修改此代码,以便我仍然可以处理CSV中的好记录并在异常情况下捕获坏记录。谢谢。

1 个答案:

答案 0 :(得分:0)

您可以在考虑无效行的情况下阅读CSV,然后过滤您认为必要的任何行。

val spark = org.apache.spark.sql.SparkSession.builder
  .master("local")
  .appName("Spark CSV Reader")
  .getOrCreate

// input
val df = spark.read
  .format("csv")
  .option("header", "true") //reading the headers
  .option("mode", "DROPMALFORMED") // discard invalid rows
  .load("INPUT FILE")

// output
df.toDF("fileId", "fileContents")
  .filter( row => row.getString(0).forall(_.isDigit) ) // eg first column is a number
  .write
  .format("com.databricks.spark.csv")
  .option("header", "true")
  .save("OUTPUT FILE")