我正在尝试使用Simba JDBC Driver(bigquery jdbc 4.2)从apache spark 2.2.0查询bigquery
这是我的代码:
import spark.implicits._
import org.apache.spark.sql.SQLContext
val sqlcontext = new org.apache.spark.sql.SQLContext(sc)
val pushdown_query = "(select * from mydb.mytable) AS T"
val dataframe_bq = sqlcontext.read.format("jdbc").option("url","jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;ProjectId=xxxx;OAuthType=0;OAuthServiceAcctEmail==xxxxxxx@xxxxxx.iam.gserviceaccount.com;OAuthPvtKeyPath=/path/file.json;").option("driver", "com.simba.googlebigquery.jdbc42.Driver").option("dbtable", pushdown_query).load()
dataframe_bq.show()
这是错误:
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 3.0 failed 1 times, most recent failure: Lost task 0.0 in stage 3.0 (TID 3, localhost, executor driver): java.sql.SQLDataException:
[Simba][JDBC](10140) Error converting value to Timestamp.
任何数据类型都可能发生转换错误,例如:
[Simba][JDBC](10140) Error converting value to Long.
Spark 2.x让每个columnName都被双引号!
所以例如SELECT UserID,UserName FROM USERS
将被操纵为SELECT“UserID”,“UserName”FROM USERS
数据框看起来像这样:
+------+--------+
|UserID|UserName|
+------+--------+
|UserID|UserName|
|UserID|UserName|
|UserID|UserName|
+------+--------+
建议的解决方案是编写自定义spark JDBC方言,但我还不能让它正常运行。
如果您能告诉我如何解决此问题,我感谢您。 提前谢谢。
答案 0 :(得分:1)
问题是,一种预先注册的jdbc方言在字段名周围添加了额外的引号。
所以查询-select column1,column2 from table
变成了select "column1","column2" from table
要解决spark中的问题,请在创建spark上下文之后和创建数据框之前添加以下代码。 [此解决方案专用于SIMBA驱动程序] 。
JdbcDialects.registerDialect(new JdbcDialect() {
override def canHandle(url: String): Boolean = url.toLowerCase.startsWith("jdbc:bigquery:")
override
def quoteIdentifier(column: String): String = column
})
答案 1 :(得分:0)
面对同样的问题。
如果需要使用Spark JDBC,除了使用/实现自定义JDBC方言外,没有其他选择。您可以看一下https://github.com/trK54Ylmz/spark-bigquery,它做了些微的改动对我有用。
如果不需要JDBC,您还可以尝试以下可用的连接器之一:Spotify(目前处于维护模式),Dataproc的Google本机connector(不幸的是非常有限)或{ {3}}第三方版本,看起来很有希望。
答案 2 :(得分:0)
要解决此问题,我必须编辑Apache Spark 2.1版源代码,并使用以下过程重新编译它以处理此问题:
1)先决条件
Maven 3.3.9 or newer and Java 8+
2)下载spark源代码,在我的情况下是2.1版
3)更新源代码,以防止Spark在列名中添加双引号!,搜索下面的代码并相应地替换它。
编辑此功能:
def quoteIdentifier(colName: String): String = {
s""""$colName""""
}
并使它像这样:
def quoteIdentifier(colName: String): String = {
return colName
}
4)用Maven构建它
Install maven 3.3.9 or above and java 8 and then build it:
./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Psparkr -Phadoop-2.7 -Phive -Phive-thriftserver -Pmesos -Pyarn
希望对您有帮助。
答案 3 :(得分:0)
当我将Simba jdbc驱动程序用于Spark时,选项 UseNativeQuery = 0 解决了以下问题:
[Simba][JDBC](10140) Error converting value to Timestamp
所以希望我不必开发任何特定的方言。