Dav*_*fin 47 apache-spark apache-spark-sql
如果我想创建一个StructType(即a DataFrame.schema)a case class,是否有办法在不创建的情况下创建DataFrame?我可以轻松地做到:
case class TestCase(id: Long)
val schema = Seq[TestCase]().toDF.schema
Run Code Online (Sandbox Code Playgroud)
但实际创建一个DataFrame我想要的只是模式似乎有点过分.
(如果你很好奇,问题背后的原因是我正在定义一个UserDefinedAggregateFunction,并且这样做会覆盖一些返回的方法,StructTypes并使用case类.)
Tza*_*har 71
你可以这样做SQLContext.createDataFrame:
import org.apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[TestCase].dataType.asInstanceOf[StructType]
Run Code Online (Sandbox Code Playgroud)
小智 61
我知道这个问题差不多已经有一年了,但是我发现它并认为其他人也可能想知道我刚学会使用这种方法:
import org.apache.spark.sql.Encoders
val mySchema = Encoders.product[MyCaseClass].schema
Run Code Online (Sandbox Code Playgroud)
如果有人想为自定义Java bean执行此操作:
ExpressionEncoder.javaBean(Event.class).schema().json()
Run Code Online (Sandbox Code Playgroud)
无需手动复制用于创建Encoder传递给的隐式对象的逻辑toDF,您可以直接使用它(或者,更准确地说,以与 相同的方式隐式使用toDF):
// spark: SparkSession
import spark.implicits._
implicitly[Encoder[MyCaseClass]].schema
Run Code Online (Sandbox Code Playgroud)
不幸的是,这实际上是从同一个问题的困扰如使用org.apache.spark.sql.catalyst或Encoders作为其他答案:该Encoder特征是实验性的。
这是如何运作的?该toDF方法对Seq来自一个DatasetHolder,其经由隐式创建localSeqToDatasetHolder经由进口spark.implicits._。该函数定义如下:
implicit def localSeqToDatasetHolder[T](s: Seq[T])(implicit arg0: Encoder[T]): DatasetHolder[T]
Run Code Online (Sandbox Code Playgroud)
如您所见,它接受一个implicit Encoder[T]参数,对于 a case class,可以通过newProductEncoder(也可以通过导入spark.implicits._)来计算。我们可以Encoder通过方便scala.Predef.implicitly(默认情况下在范围内,因为它来自 from Predef)来重现这个隐式逻辑来为我们的案例类获取 an ,它只会返回其请求的隐式参数:
def implicitly[T](implicit e: T): T
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17708 次 |
| 最近记录: |