2016-04-20 8 views
18

Wenn ich ein StructType (das heißt ein DataFrame.schema) aus einem case class schaffen wollte, ist es eine Möglichkeit, es zu tun, ohne ein DataFrame zu schaffen? Ich kann leicht tun:Generieren ein Funke StructType/Schema aus einer Fallklasse

case class TestCase(id: Long) 
val schema = Seq[TestCase]().toDF.schema 

Aber es scheint übertrieben, tatsächlich ein DataFrame zu erstellen, wenn alles, was ich möchte das Schema.

(Wenn Sie neugierig sind, ist der Grund für die Frage, dass ich eine UserDefinedAggregateFunction bin definieren, und Sie so außer Kraft setzen ein paar Methoden zu tun, die StructTypes und ich verwende Fallklassen zurück.)

Antwort

28

Sie tun können es ist die gleiche Art und Weise SQLContext.createDataFrame tut es:

import org.apache.spark.sql.catalyst.ScalaReflection 
val schema = ScalaReflection.schemaFor[TestCase].dataType.asInstanceOf[StructType] 
+0

Dank - war nicht ganz schafften es in 'o.a.s.sql.catalyst' noch. Und wenn ich gerade nachgedacht hätte, hätte ich mit createDataFrame genau wie du begonnen. ':-(' –

+0

Süße, du kannst sogar '... schemaFor [(Long, Int, Long)] ...' –

+0

Keine Sorge - ich habe es nur leicht gefunden, weil ich vor einiger Zeit etwas ähnliches versucht habe ;) Und ja - würde für jedes 'Produkt' funktionieren, danke Scala! –

27

ich weiß, diese Frage fast ein Jahr alt ist, aber ich kam über sie und dachte, andere, die auch wissen, tun möchten vielleicht, dass ich gerade diesen Ansatz verwenden gelernt:

import org.apache.spark.sql.Encoders 
val mySchema = Encoders.product[MyCaseClass].schema 
+0

Beachten Sie, dass das' Encoders'-Objekt mit der '@ Experimental'-Anmerkung markiert ist: "Eine experimentelle API für den Benutzer. Experimentelle APIs können sich ändern oder in Moll entfernt werden Versionen von Spark, oder als erstklassige Spark-APIs übernommen werden. " Entdeckt, dass in einem Versuch, Pro/Contra der verschiedenen Ansätze (aktuelle Antwort vs angenommene Antwort) herauszufinden. –

2

falls jemand möchte dies für eine benutzerdefinierte Java Bean tun:

ExpressionEncoder.javaBean(Event.class).schema().json() 
+1

Es gibt auch '' 'Encoders.bean (Event.class) .schema()' '' was ich nehme, tut das gleiche . –

Verwandte Themen