一.DataFrame 和Rdd 相互转换关系
1.df 转化为rdd
val df: DataFrame = hiveContext.sql("select * from game_sdk") df.foreachPartition(rdd => { rdd.foreach(row => { val a: Row = row; println(row.getAs[Int]("old_game_id")) }) })
df.printSchema() |
2.rdd转化为 df
/** * 读取 bi 的 bi_gamepublic_regi_detail 表 并注册相应的表 * * @param sc * @param hiveContext * @param startTime * @param endTime * * 可以带时间参数,在时间范围小的情况下,不会造成内出溢出 */ def readRegiDeatials(sc: SparkContext, hiveContext: HiveContext, startTime: String, endTime: String) = {
val conn: Connection = JdbcUtil.getConn(); val sql = "select game_id,parent_channel,child_channel,ad_label,imei,regi_hour from bi_gamepublic_regi_detail where date(regi_hour)>='startTime' and date(regi_hour)<='endTime'" .replace("startTime", startTime).replace("endTime", endTime) val stmt = conn.createStatement(); val results = stmt.executeQuery(sql); var rows = new ArrayBuffer[Row]() while (results.next()) { rows.+=(RowFactory.create(Integer.valueOf(results.getInt(1).toString), results.getString(2), results.getString(3), results.getString(4), results.getString(5), results.getString(6))); } val rowsRDD = sc.parallelize(rows); val schema = (new StructType).add("game_id", IntegerType).add("parent_channel", StringType).add("child_channel", StringType).add("ad_label", StringType).add("imei", StringType).add("regi_hour", StringType) hiveContext.createDataFrame(rowsRDD, schema).persist().registerTempTable("bi_gamepublic_regi_detail"); } |
由以上可知道 : DataFrame= RDD + Schema:DataFrame 转换为 Rdd 时 就是去掉DataFrame 的Schema 信息,Rdd转化为 DataFrame 的时候 就是加上 Schema 信息
二.DataFrame 和Rdd 相互转换 时,数据 Row 的 Schema 信息
val df: DataFrame = hiveContext.sql("select * from game_sdk") df.rdd.foreachPartition(rdd => { rdd.foreach(row => { val a: Row = row; println(row.getAs[Int]("old_game_id")) }) }) df.rdd.printSchema() 报错 |
val regiRdd = sctextFile(…).filter(t => { val arr: Array[String] = t.split("\\|"); arr(0).contains("bi_regi") && arr.length > 14 && StringUtils.isNumber(arr(4)) }).map(t => { val arr: Array[String] = t.split("\\|"); // game_account game_id parent_channel child_channel ad_label reg_time imei Row(arr(3), arr(4).toInt, StringUtils.getArrayChannel(arr(13))(0), StringUtils.getArrayChannel(arr(13))(1), StringUtils.getArrayChannel(arr(13))(2), arr(5), arr(14)) }); regiRdd.foreach(row=>{ println(row.get(0)) println(row.getAs[Int]("game_id"))报错 }) |
由以上可知道 :
Row 也具有自己的 Schema 信息,DataFrame 转换为 Rdd 时,DataFrame 的 Schema 去除,Row 的信息并没有去除,
Rdd转化为 DataFrame 的时候,同时为 DataFrame 和 Row 添加 Schema 信息