在任何地方导入spark implicits的解决方法

时间:2017-08-16 23:10:53

标签: scala apache-spark spark-dataframe apache-spark-2.0 implicits

我是Spark 2.0的新手,并在我们的代码库中使用数据集。我有点注意到我需要在代码中到处import spark.implicits._。例如:

File A
class A {
    def job(spark: SparkSession) = {
        import spark.implcits._
        //create dataset ds
        val b = new B(spark)
        b.doSomething(ds)
        doSomething(ds)
    }
    private def doSomething(ds: Dataset[Foo], spark: SparkSession) = {
        import spark.implicits._
        ds.map(e => 1)            
    }
}

File B
class B(spark: SparkSession) {
    def doSomething(ds: Dataset[Foo]) = {
        import spark.implicits._
        ds.map(e => "SomeString")
    }
}

我想问的是,是否有更清洁的方法可以做到

ds.map(e => "SomeString")

没有在我执行地图的每个功能中导入implicits?如果我不导入它,我会收到以下错误:

  

错误:(53,13)无法找到存储在数据集中的类型的编码器。导入spark.implicits.支持原始类型(Int,String等)和产品类型(case类)。将来版本中将添加对序列化其他类型的支持。

2 个答案:

答案 0 :(得分:0)

classobject而不是每个函数中进行导入会有所帮助。对于“文件A”和“文件B”示例:

File A
class A {
    val spark = SparkSession.builder.getOrCreate()
    import spark.implicits._

    def job() = {
        //create dataset ds
        val b = new B(spark)
        b.doSomething(ds)
        doSomething(ds)
    }

    private def doSomething(ds: Dataset[Foo]) = {
        ds.map(e => 1)            
    }
}

File B
class B(spark: SparkSession) {
    import spark.implicits._

    def doSomething(ds: Dataset[Foo]) = {    
        ds.map(e => "SomeString")
    }
}

通过这种方式,您可以获得可管理的imports

不幸的是,据我所知,没有其他方法可以进一步减少进口数量。这是因为在执行实际SparkSession时需要import对象。因此,这是最好的。

答案 1 :(得分:0)

您可以在每个调用的方法中重用现有的SparkSession。通过在方法内部创建本地val-

val spark: org.apache.spark.sql.SparkSession = org.apache.spark.sql.SparkSession.active

然后

import spark.implicits._

到目前为止,对我来说还不错。