web-dev-qa-db-ja.com

Spark SQLからCSVにデータをエクスポートする方法

このコマンドはHiveQLで機能します。

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

しかし、Spark SQLを使用すると、org.Apache.spark.sql.Hive.HiveQlスタックトレースでエラーが発生します。

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

Spark SQLでCSVへのエクスポート機能を作成するようにガイドしてください。

41
shashankS

以下のステートメントを使用して、データフレームの内容をCSV形式で書き込むことができますdf.write.csv("/data/home/csv")

データフレーム全体を単一のCSVファイルに書き込む必要がある場合は、df.coalesce(1).write.csv("/data/home/sample.csv")を使用します

spark 1.xの場合、spark-csv を使用して、結果をCSVファイルに書き込むことができます

以下scalaスニペットが役立ちます

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")

内容を単一のファイルに書き込むには

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

Spark 2.Xspark-csvネイティブデータソース として統合されているため。したがって、必要なステートメントは(windows)に簡素化されます

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

またはUNIX

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

上記のspark-csvでの答えは正しいですが、問題があります-ライブラリは、データフレームパーティションに基づいていくつかのファイルを作成します。そして、これは通常必要なものではありません。したがって、すべてのパーティションを1つに結合できます。

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

そして、libの出力(名前「part-00000」)を希望のファイル名に変更します。

このブログ投稿で詳細を説明しています: https://fullstackml.com/2015/12/21/how-to-export-data-frame-from-Apache-spark/

26
Dmitry Petrov

最も簡単な方法は、DataFrameのRDDにマップし、mkStringを使用することです。

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

Spark 1.5(またはそれ以前)df.map(r=>r.mkString(","))は、CSVエスケープが必要な場合に同じことを行います。そのためにApache commons langを使用できます。例えばこれが私たちが使用しているコードです

 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

エラーメッセージは、これがクエリ言語でサポートされている機能ではないことを示しています。ただし、RDDインターフェイス(df.rdd.saveAsTextFile)を使用して、通常どおり任意の形式でDataFrameを保存できます。または、 https://github.com/databricks/spark-csv をチェックアウトできます。

1
Daniel Darabos

Spark-csvの助けを借りて、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