web-dev-qa-db-ja.com

Spark)で空のdataFrameを作成する方法

AvroベースのHiveテーブルのセットがあり、それらからデータを読み取る必要があります。 Spark-SQLはHiveserdesを使用してHDFSからデータを読み取るため、HDFSを直接読み取るよりもはるかに低速です。そのため、データブリックのSpark-Avro jarを使用して、基になるHDFSディレクトリからAvroファイルを読み取りました。

テーブルが空の場合を除いて、すべて正常に動作します。次のコマンドを使用して、Hiveテーブルの.avscファイルからスキーマを取得できましたが、エラーが発生します "Avroファイルが見つかりません"

val schemaFile = FileSystem.get(sc.hadoopConfiguration).open(new Path("hdfs://myfile.avsc"));

val schema = new Schema.Parser().parse(schemaFile);

spark.read.format("com.databricks.spark.avro").option("avroSchema", schema.toString).load("/tmp/myoutput.avro").show()

回避策:

そのディレクトリに空のファイルを配置しましたが、同じことが正常に機能します。

同じことを達成する他の方法はありますか? conf設定か何かのように?

3
Vinay Kumar

EmiCareOfCell44の答えと同様に、もう少しエレガントで「空」です

val emptySchema = StructType(Seq())
val emptyDF = spark.createDataFrame(spark.sparkContext.emptyRDD[Row],
                emptySchema)
1
Y.G.

空のDataFrameを作成するには:

val my_schema = StructType(Seq(
    StructField("field1", StringType, nullable = false),
    StructField("field2", StringType, nullable = false)
  ))

val empty: DataFrame = spark.createDataFrame(spark.sparkContext.emptyRDD[Row], my_schema)

多分これは役立つかもしれません

1
EmiCareOfCell44

EmptyRDDを使用する必要はありません。これがPySpark2.4で私のために働いたものです:

empty_df = spark.createDataFrame([], schema) # spark is the Spark Session

別のデータフレームのスキーマがすでにある場合は、次のようにすることができます。

schema = some_other_df.schema

そうでない場合は、次に、空のデータフレームのスキーマを手動で作成します。次に例を示します。

schema = StructType([StructField("col_1", StringType(), True),
                     StructField("col_2", DateType(), True),
                     StructField("col_3", StringType(), True),
                     StructField("col_4", IntegerType(), False)]
                     )

これがお役に立てば幸いです。

1
luvrock

Sparkバージョンに応じて、リフレクションウェイを使用できます。 SchemaConverters には、スキーマをStructTypeに変換するジョブを実行するプライベートメソッドがあります。 (正直に言うとなぜプライベートなのかわからないので、他の状況で本当に役立ちます)scala Reflectionを使用すると、次の方法で実行できるはずです。

import scala.reflect.runtime.{universe => ru}
import org.Apache.avro.Schema
import org.Apache.spark.sql.Row
import org.Apache.spark.sql.types.{StructType, StructField, StringType, IntegerType}

var schemaStr = "{\n \"type\": \"record\",\n \"namespace\": \"com.example\",\n \"name\": \"FullName\",\n \"fields\": [\n { \"name\": \"first\", \"type\": \"string\" },\n      { \"name\": \"last\", \"type\": \"string\" }\n  ]\n }"
val schema = new Schema.Parser().parse(schemaStr);

val m = ru.runtimeMirror(getClass.getClassLoader)
val module = m.staticModule("com.databricks.spark.avro.SchemaConverters")
val im = m.reflectModule(module)
val method = im.symbol.info.decl(ru.TermName("toSqlType")).asMethod

val objMirror = m.reflect(im.instance)
val structure = objMirror.reflectMethod(method)(schema).asInstanceOf[com.databricks.spark.avro.SchemaConverters.SchemaType]
val sqlSchema = structure.dataType.asInstanceOf[StructType]
val empty = spark.createDataFrame(spark.sparkContext.emptyRDD[Row], sqlSchema)

empty.printSchema
0
hlagos