2016-04-20 61 views
18

如果我想从case class中创建StructType(即DataFrame.schema),有没有办法在不创建DataFrame?我可以很容易做到:从案例类别生成Spark StructType/Schema

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

但似乎矫枉过正,真正创建一个DataFrame当所有我要的是架构。

(如果你很好奇,这个问题背后的原因是,我定义UserDefinedAggregateFunction,并且这样做你重写了几个返回StructTypes方法,我用例类。)

回答

28

你可以做用同样的方式SQLContext.createDataFrame做的:

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

谢谢 - 还没有完全把它做成'o.a.s.sql.catalyst'呢。如果我一直在想,就像你一样,我会用'createDataFrame'开始。 ':-(' –

+0

甜,你甚至可以做'... schemaFor [(Long,Int,Long)] ...' –

+0

不用担心 - 我只是很容易找到它,因为我前一段时间尝试过类似的东西;)是的 - 适用于任何'产品',谢谢你斯卡拉! –

27

我知道这个问题几乎是一岁,但我碰到它,并认为其他人谁也做可能想知道,我刚刚学会了使用这种方法:

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

请注意 - 编码器对象被标记为'@ Experimental'注释:“一个实验性的面向用户的API。实验性API可能会改变或被删除Spark的版本,或者作为一流的Spark API被采用。“发现为了弄清楚不同方法的优缺点(当前答案vs接受的答案) –

2

万一有人想自定义的Java Bean做到这一点:

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

还有'''Encoders.bean(Event.class).schema()'''我假设它也是一样的。 –