spark 2.0 用 json 读取 csv

Lio*_*ber 3 csv scala apache-spark

我有一个 CSV 文件,如下所示:

"a","b","c","{""x"":""xx"",""y"":""yy""}"
Run Code Online (Sandbox Code Playgroud)

当我使用 java CSV reader ( au.com.bytecode.opencsv.CSVParser) 时,它会在我指示时设法解析字符串defaultEscapeChar = '\u0000'

当我尝试使用 spark 2.2 CSV 阅读器阅读它时,它失败了,无法将其拆分为 4 列。这是我尝试过的:

val df = spark.read.format("csv")
              .option("quoteMode","ALL")
              .option("quote", "\u0000")
              .load("s3://...")
Run Code Online (Sandbox Code Playgroud)

我也尝试过,option("escape", "\u0000") 但没有运气。

我需要选择哪些 CSV 选项才能正确解析此文件?

MxR*_*MxR 5

您实际上很接近,正确的选择是option("escape", "\"") 鉴于最近的 spark 版本(2.2+ 或更早版本),下面的片段

import org.apache.spark.sql.{Dataset, SparkSession}

object CsvJsonMain {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("CsvJsonExample").master("local").getOrCreate()

    import spark.sqlContext.implicits._
    val csvData: Dataset[String] = spark.sparkContext.parallelize(List(
      """
        |"a","b","c","{""x"":""xx"",""y"":""yy""}"
      """.stripMargin)).toDS()

    val frame = spark.read.option("escape", "\"").csv(csvData)
    frame.show()
  }
}
Run Code Online (Sandbox Code Playgroud)

会产生

+---+---+---+-------------------+
|_c0|_c1|_c2|                _c3|
+---+---+---+-------------------+
|  a|  b|  c|{"x":"xx","y":"yy"}|
+---+---+---+-------------------+
Run Code Online (Sandbox Code Playgroud)

spark 无法开箱即用解析此类 csv 的原因是默认转义值是 '\' 符号,如CSVOptions的第 91 行所示,显然它不适用于默认的 json 引号转义。

它在 spark 2.0 之前使用 databricks-csv 库工作的根本原因是底层 csv 引擎曾经是commons-csv和转义字符默认为 null 将允许库检测 json 和它的转义方式。由于 2.0 csv 功能是 spark 本身的一部分,并且使用uniVocity CSV 解析器,它不提供这种“魔法”但显然更快。

PS 不要忘记在写入 csv 文件时指定转义,如果您想按原样保留 json 数据。

frame.write.option("quoteAll","true").option("escape", "\"").csv("csvFileName") 
Run Code Online (Sandbox Code Playgroud)