2017-05-09 5 views
1

Ich versuche, eine RDD meiner benutzerdefinierten Objekte (eine Java-Klasse) in einen Dataframe zu konvertieren, ich habe einfach die Methode hiveContext.createDataframe die Klasse des Objekts angeben. Das Problem ist, dass der Datenrahmen mit Spalten in einer seltsamen Reihenfolge erstellt wird, und sobald ich den DF in Hive schreibe, sind die Werte in den falschen Spalten. Hier ist mein Code:Spark createDataframe aus RDD der Objekte, Spaltenreihenfolge

var objectRDD = tableDF.map((r: Row) => new Attuatore(r(0),r(1)...)) [.. operations with the RDD ..] val resultDF = hiveContext.createDataFrame(objectRDD, classOf[Attuatore]) resultDF.write.mode("append").saveAsTable(outputTable)

Die einzige Lösung, die ich dafür, dass die Felder in der richtigen Reihenfolge bisher gefunden ist, die RDD [Attuatore] zu einem RDD [Row] konvertieren zurück, und dann createDataFrame rufen() Spezifizierung des Schemas, aber da ich dies mit vielen Klassen tun muss, würde ich bevorzugen, dass der erste Ansatz einen viel saubereren Code hat.

Antwort

1

Da die Dokumentation für HiveContext.createDataFrame sagt

Da es für die Felder in einer Java Bean, SELECT * Abfragen kehren die Spalten in einer nicht definierten Reihenfolge keine garantierte Bestellung ist.

Also, wenn Sie Felder in einer definierten Reihenfolge setzen müssen, müssen Sie es explizit tun, z.

val MY_COLUMNS = Seq("field1", "field2", ...) 
val conformedDF = resultDF.select(MY_COLUMNS.map(col(_)):_*) 
conformedDF.write... 
+0

Ihr Code nicht für mich arbeiten, heißt es erwartet Seq [Spalte] gefunden Seq [ANY], aber ich denke, dass mit nur val conformedDF = resultDF.select ("Feld1", "Feld2". ..) wird funktionieren –

+0

Sorry, es gab einen Tippfehler, seit behoben. Meine Erwartung war, dass Sie die Liste der Spalten (in der gewünschten Reihenfolge) von woanders abrufen (Reflektion, Metadaten usw.), anstatt sie inline zu kodieren. Offensichtlich ist Letzteres einfacher, wenn Sie damit einverstanden sind. – halversonp

+0

Ich bekomme die Spalten aus der Java-Klasse, weißt du, wie man ein Array [String] konvertiert, um es an die select-Methode zu übergeben? Bei der Mutter. Ich benutze (cols.head, cols.tail: _ *) wo cols ist das Array (ich weiß nicht, Scala) –