web-dev-qa-db-fra.com

Comment exporter des données de Spark SQL au format CSV

Cette commande fonctionne avec HiveQL:

insert overwrite directory '/data/home.csv' select * from testtable;

Mais avec Spark SQL, je reçois une erreur avec une trace de pile org.Apache.spark.sql.Hive.HiveQl:

Java.lang.RuntimeException: Unsupported language features in query:
    insert overwrite directory '/data/home.csv' select * from testtable

Guidez-moi s'il vous plaît pour écrire la fonction d'exportation au format CSV dans Spark SQL.

41
shashankS

Vous pouvez utiliser l'instruction ci-dessous pour écrire le contenu de la structure de données au format CSV df.write.csv("/data/home/csv")

Si vous avez besoin d'écrire l'intégralité du cadre de données dans un seul fichier CSV, utilisez df.coalesce(1).write.csv("/data/home/sample.csv")

Pour spark 1.x, vous pouvez utiliser spark-csv pour écrire les résultats dans des fichiers CSV.

Au-dessous de scala un extrait de code aiderait

import org.Apache.spark.sql.Hive.HiveContext
// sc - existing spark context
val sqlContext = new HiveContext(sc)
val df = sqlContext.sql("SELECT * FROM testtable")
df.write.format("com.databricks.spark.csv").save("/data/home/csv")

Pour écrire le contenu dans un seul fichier

import org.Apache.spark.sql.Hive.HiveContext
// sc - existing spark context
val sqlContext = new HiveContext(sc)
val df = sqlContext.sql("SELECT * FROM testtable")
df.coalesce(1).write.format("com.databricks.spark.csv").save("/data/home/sample.csv")
72
sag

Depuis Spark 2.Xspark-csv est intégré en tant que source de données native . Par conséquent, l'instruction nécessaire simplifie à (Windows)

df.write
  .option("header", "true")
  .csv("file:///C:/out.csv")

ou UNIX

df.write
  .option("header", "true")
  .csv("/var/out.csv")
45
Boern

La réponse ci-dessus avec spark-csv est correcte, mais il existe un problème: la bibliothèque crée plusieurs fichiers en fonction du partitionnement du cadre de données. Et ce n’est pas ce dont nous avons habituellement besoin. Vous pouvez donc combiner toutes les partitions en une:

df.coalesce(1).
    write.
    format("com.databricks.spark.csv").
    option("header", "true").
    save("myfile.csv")

et renommez la sortie de la lib (nom "part-00000") en un nom de fichier souhaité.

Cet article de blog fournit plus de détails: https://fullstackml.com/2015/12/21/how-to-export-data-frame-from-Apache-spark/

26
Dmitry Petrov

Le moyen le plus simple consiste à mapper sur le RDD du DataFrame et à utiliser mkString:

  df.rdd.map(x=>x.mkString(","))

À partir de Spark 1.5 (ou même avant), df.map(r=>r.mkString(",")) ferait de même si vous voulez échapper au format CSV, vous pouvez utiliser Apache commons lang pour cela. par exemple. voici le code que nous utilisons

 def DfToTextFile(path: String,
                   df: DataFrame,
                   delimiter: String = ",",
                   csvEscape: Boolean = true,
                   partitions: Int = 1,
                   compress: Boolean = true,
                   header: Option[String] = None,
                   maxColumnLength: Option[Int] = None) = {

    def trimColumnLength(c: String) = {
      val col = maxColumnLength match {
        case None => c
        case Some(len: Int) => c.take(len)
      }
      if (csvEscape) StringEscapeUtils.escapeCsv(col) else col
    }
    def rowToString(r: Row) = {
      val st = r.mkString("~-~").replaceAll("[\\p{C}|\\uFFFD]", "") //remove control characters
      st.split("~-~").map(trimColumnLength).mkString(delimiter)
    }

    def addHeader(r: RDD[String]) = {
      val rdd = for (h <- header;
                     if partitions == 1; //headers only supported for single partitions
                     tmpRdd = sc.parallelize(Array(h))) yield tmpRdd.union(r).coalesce(1)
      rdd.getOrElse(r)
    }

    val rdd = df.map(rowToString).repartition(partitions)
    val headerRdd = addHeader(rdd)

    if (compress)
      headerRdd.saveAsTextFile(path, classOf[GzipCodec])
    else
      headerRdd.saveAsTextFile(path)
  }
9
Arnon Rotem-Gal-Oz

Le message d'erreur suggère que ce n'est pas une fonctionnalité prise en charge dans le langage de requête. Mais vous pouvez enregistrer un DataFrame dans n’importe quel format, comme d’habitude, via l’interface RDD (df.rdd.saveAsTextFile). Ou vous pouvez consulter https://github.com/databricks/spark-csv .

1
Daniel Darabos

Avec spark-csv, nous pouvons écrire dans un fichier CSV.

val dfsql = sqlContext.sql("select * from tablename")
dfsql.write.format("com.databricks.spark.csv").option("header","true").save("output.csv")`
1
Uva Prakash P