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.
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")
Depuis Spark 2.X
spark-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")
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/
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)
}
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 .
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")`