Spark JDBC伪列不起作用

时间:2018-04-12 04:00:04

标签: apache-spark jdbc

对于我的用例,我试图使用spark JDBC读取一个大的oracle表。由于我的表格中没有整数类型列,因此我使用rownum作为paritionColumn

这是我的spark查询的样子:(用于测试我使用的表只有22000行。)

val df = spark.read.jdbc(jdbcUrl = url, table = select * from table1, 
                         columnName= "rownum", lowerBound = 0, upperBound = 22000, 
                         numPartitions = 3, connectionProperties = oracleProperties)

理想情况下,它应该返回3个分区,每个分区有近7000行。但是当我在数据帧的每个分区上运行计数时,我可以看到只有一个分区有行而其他分区都是0。

df.rdd.mapPartitionsWithIndex{case(i, rows) => Iterator((i, rows.size))}.toDF().show()

输出:

+---+----+
| _1| _2 |    
+---+----+    
| 0 |7332|    
| 1 | 0  |    
| 2 | 0  |    
+---+----+

请问你为什么只能在一个分区中返回行?

我的来源是Oracle数据库。使用oracle jdbc驱动 oracle.jdbc.driver.OracleDriver jar - > ojdbc7.jar

参考帖子:http://apache-spark-user-list.1001560.n3.nabble.com/Question-on-using-pseudo-columns-in-spark-jdbc-options-td30154.html

1 个答案:

答案 0 :(得分:-1)

经过一些谷歌搜索后,我能够使它工作。我做了一些

我试图使用Spark jdbc从Oracle数据库中读取数据。我能够使用oracle的Pseudocolumn ROWNUM将来自spark的读取与一些hacks并行化。 诀窍是你必须为ROWNUM列添加别名,然后使用该别名列。

我想查询整个" table1"并在该表的spark中创建多个分区。

val df = spark.read.jdbc(jdbcUrl= url, table = "select * from table1", 
                         columnName="ROWNUM", lowerBound = 0, upperBound = 22000,
                          numPartitions = 3, connectionProperties = oracleProperties)

为了在Pseudocolumn上进行分区,请修改如下的查询:

val df = spark.read.jdbc(jdbcUrl= url, table = "(select t1.*, ROWNUM as num_rows from (select * from table1) t1) oracle_table1", 
                         columnName="num_rows", lowerBound = 0, upperBound = 22000,
                          numPartitions = 3, connectionProperties = oracleProperties)

这样我们实际上将psuedocolumn作为一个实际的列并用它来进行分区。