【问题标题】:scala - Resultset to spark Dataframescala - 触发数据框的结果集
【发布时间】:2016-12-13 09:38:31
【问题描述】:

我正在查询mysql表

val url = "jdbc:mysql://XXX-XX-XXX-XX-XX.compute-1.amazonaws.com:3306/pg_partner"
val driver = "com.mysql.jdbc.Driver"
val username = "XXX"
val password = "XXX"
var connection:Connection = DriverManager.getConnection(url, username, password)
val statement = connection.createStatement()
val patnerName = statement.executeQuery("SELECT id,name FROM partner")

我确实在patnerName 中得到了我的结果,但我需要转换为 Dataframe。

我可以通过以下代码打印数据:

while (patnerName.next) {
  val id = patnerName.getString("id")
  val name = patnerName.getString("name")
  println("id = %s, name = %s".format(id,name))
}

现在我如何将patnerName 转换为 DataFrame?

【问题讨论】:

    标签: scala apache-spark spark-dataframe resultset


    【解决方案1】:

    所以你必须分几个步骤来做:

    1. 定义列并准备架构
        val columns = Seq("id", "name")
        val schema = StructType(List(
          StructField("id", StringType, nullable = true),
          StructField("name", StringType, nullable = true)
        ))
    
    1. 定义如何在每次迭代时将 ResultSet 中的每条记录转换为 Row
        def parseResultSet(rs: ResultSet): Row = {
          val resultSetRecord = columns.map(c => rs.getString(c))
          Row(resultSetRecord:_*)
        }
    
    1. 定义一个函数以将您的 ResultSet 转换为 Iterator[Row]。它将使用您在上一步中定义的函数(当您在下一步中调用它时)。
        def resultSetToIter(rs: ResultSet)(f: ResultSet => Row): Iterator[Row] =
          new Iterator[Row] {
            def hasNext: Boolean = rs.next()
            def next(): Row = f(rs)
          }
    
    1. 定义一个从 Iterator[Row].toSeq 创建 RDD 的函数,该函数使用您在上一步中定义的函数。使用架构从 RDD 创建 DataFrame
        def parallelizeResultSet(rs: ResultSet, spark: SparkSession): DataFrame = {
          val rdd = spark.sparkContext.parallelize(resultSetToIter(rs)(parseResultSet).toSeq)
          spark.createDataFrame(rdd, schema) // use the schema you defined in step 1
        }
    
    1. 最后调用你的函数
        val df: DataFrame = parallelizeResultSet(patner, spark)
    

    【讨论】:

    • 我尝试了上面提到的方法,我能够创建数据框,但它正在为我创建空数据框,并没有我的结果集中的数据。
    • @Saurabh 您是否能够验证 ResultSet 是否包含任何数据?尝试rs.next(),然后用rs.getString("col_name")从当前行中选择一列,看看它是否返回数据。
    • 是的,我使用 rs.getString("col_name") 验证了我的结果集中有数据。它使用我提供的 e 结构创建了数据框。
    【解决方案2】:

    直接使用 Spark 功能怎么样?

    val jdbcDF = spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://XXX-XX-XXX-XX-XX.compute-1.amazonaws.com:3306/")
      .option("dbtable", "pg_partner")
      .option("user", "XXX")
      .option("password", "XXX")
      .load()
    

    代码取自here

    【讨论】:

    • spark.read 中的spark 指的是什么?是 sparkcontext 还是 sqlcontext
    • 在 Spark 2 中出现的是 SparkSession。你使用的是哪个 Spark 版本?
    • 我正在使用 spark 2.0.0 我在我的代码中使用这些:val sparkConf = new SparkConf().setAppName("QuaterlyAudit").setMaster("local") val sc = new SparkContext(sparkConf) val sqlContext = new org.apache.spark.sql.SQLContext(sc) sc 不工作我知道 sc 是 sparkcontext 但什么是 SparkSession
    猜你喜欢
    • 2020-11-06
    • 2015-07-26
    • 2018-03-09
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多