2017-05-09 146 views
1

我试图将自定义对象(Java类)的RDD转换为Dataframe,我只是使用指定对象类的方法hiveContext.createDataframe。问题在于数据框是按照某种奇怪的顺序创建的,而且一旦我将DF写入Hive,值就会出现在错误的列中。 这里是我的代码:Spark从RDD创建对象的数据框,列顺序

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)

我迄今为止所发现的具有正确的顺序领域唯一的解决办法是将RDD [Attuatore]转换回RDD [行],然后调用createDataFrame ()指定模式,但由于我必须用很多类来完成此操作,所以我宁愿使用第一种方法来获得更简洁的代码。

回答

1

至于HiveContext.createDataFrame的文件说

由于没有保证的顺序在一个Java Bean领域, SELECT *查询将在不确定的顺序返回列。

因此,如果您需要按照定义的顺序放置字段,则必须明确地执行此操作,例如,

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

您的代码不工作对我来说,它说,预计序列[专栏]发现序列[任何],但我认为这只是用VAL conformedDF = resultDF.select(“字段1”,“字段2”。 ..)将工作 –

+0

对不起,有一个错字,因为固定。我的期望是,你会从其他地方(反射,元数据等)获得列表的列表(以期望的顺序),而不是将它们内联硬编码。显然,后者更简单,如果你没有问题的话。 – halversonp

+0

我从Java类中得到cols,你知道如何转换一个Array [String]以便将它传递给select方法吗?妈妈。我正在使用(cols.head,cols.tail:_ *),其中cols是数组(我不知道Scala) –