SPARK read.jdbc 和自定义架构

the*_*tom 3 apache-spark

使用spark.read.format ...一次可以以非编程方式添加自定义架构,如下所示:

val df = sqlContext
.read()
.format("jdbc")
.option("url", "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true")
.option("user", "root")
.option("password", "password")
.option("dbtable", sql)
.schema(customSchema)
.load();
Run Code Online (Sandbox Code Playgroud)

但是,使用spark.read.jdbc,我似乎无法执行相同的操作或找到与上述操作相同的语法。我错过了什么或者 SPARK 2.x 中的情况发生了变化吗?我在手册中读到了这一点:... Spark 自动从数据库表中读取模式并将其类型映射回 Spark SQL 类型。... 大概我想要做的事情不再可能,如上面的例子。

val dataframe_mysql = spark.read.jdbc(jdbcUrl, "(select k, v from sample) e ", connectionProperties)
Run Code Online (Sandbox Code Playgroud)

我最终尝试了这个:

val dataframe_mysql = spark.read.schema(openPositionsSchema).jdbc(jdbcUrl, "(select k, v from sample) e ", connectionProperties)
Run Code Online (Sandbox Code Playgroud)

并得到这个:

org.apache.spark.sql.AnalysisException: User specified schema not supported with `jdbc`;
Run Code Online (Sandbox Code Playgroud)

从某种程度上来说,这似乎是一种倒退。

小智 6

我不同意这个答案。

您可以使用您的方法或通过设置属性来提供自定义架构:

 connectionProperties.put("customSchema", schemachanges);
Run Code Online (Sandbox Code Playgroud)

其中架构以格式“字段名称”“新数据类型”更改,...:

 "key String, value DECIMAL(20, 0)"
Run Code Online (Sandbox Code Playgroud)

如果 key 是原始表中的数字,它将生成一个 SQL 查询,如“key::character Varying, value::numeric(20, 0)”

它比强制转换更好,因为强制转换是在原始类型中选择后执行的映射操作,而自定义架构不是。

我有一个案例,当spark无法从postgres Numeric中选择NaN时,因为它将数字映射到不允许NaN的java BigDecimal,所以每次读取这些值时spark作业都会失败。Cast 产生了相同的结果。然而,在将方案更改为 String 或 Double 后,它能够正确读取它。

Spark 文档:https://spark.apache.org/docs/latest/sql-data-sources-jdbc.html