Apache spark SPARK read.jdbc&;自定义模式

Apache spark SPARK read.jdbc&;自定义模式,apache-spark,Apache Spark,使用spark.read.format。。。once可以非编程方式添加自定义架构,如下所示: 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

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

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();
但是,使用spark.read.jdbc,我似乎无法做到与上述相同的操作,也无法找到与上述操作相同的语法。在SPARK 2.x中,我遗漏了什么,或者这有什么变化?我在手册中读到:。。。Spark自动从数据库表中读取模式,并将其类型映射回Spark SQL类型大概我正在尝试做的事情不再像上面的例子那样可能了

val dataframe_mysql = spark.read.jdbc(jdbcUrl, "(select k, v from sample) e ", connectionProperties)
我最后尝试了这个:

val dataframe_mysql = spark.read.schema(openPositionsSchema).jdbc(jdbcUrl, "(select k, v from sample) e ", connectionProperties)
得到这个:

org.apache.spark.sql.AnalysisException: User specified schema not supported with `jdbc`;
在某种程度上似乎是一种倒退

。在SPARK 2.x中,我遗漏了什么,或者这有什么变化

你不会错过任何东西。从不支持使用JDBC源代码在读取时修改架构。输入已键入,因此没有位置放置
架构


如果类型不令人满意,只需将结果转换为所需类型。

我不同意答案

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

 connectionProperties.put("customSchema", schemachanges);
其中,架构的格式更改为“字段名”“新数据类型”…:

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

它优于强制转换,因为强制转换是在原始类型中选择它之后执行的映射操作,而自定义模式不是

我有一个例子,spark不能从postgres Numeric中选择NaN,因为它将数值映射到不允许NaN的java BigDecimal,所以每次读取这些值时spark作业都失败。卡斯特也产生了同样的结果。然而,在将方案更改为字符串或双精度后,它能够正确地读取它


Spark文档:

您可以使用自定义模式并输入属性参数。你可以在

创建一个变量: c_模式='id_type INT'

属性配置: 配置={“用户”:“xxx”, “密码”:“yyy”, “驱动程序”:“com.mysql.jdbc.driver”, “customSchema”:c_schema}

阅读表格并创建DF: df=spark.read.jdbc(url=jdbc\u url,table='table\u name',properties=config)

您必须使用相同的列名,它只会更改列
您可以将其放入自定义模式中。

在spark 2中,您可以将模式作为spark.read.format().schema传递。。但是,spark.read.jdbc返回数据集。您可以将架构指定给DataFrameReader,而不是指定给Dataset。一个奇怪的解决方案可能是。。RDD RDD=sparkSession.read().jdbc(“,”,null).RDD();createDataFrame(rdd,模式);它只返回数据集,不过我试过用Java。您还可以使用createDataSet函数并使用scala和get提供适当的encoderI am,在本例中为dataframe_mysql:org.apache.spark.sql.dataframe=[k:int,v:int]我似乎在DataRicks文档中读到了一些类似的内容。在我的示例中,我只是将模式放在连接属性中,这些属性提供给jdbc调用。它在spark 2.3.*和2.4.*上运行。没有在不同的版本上测试。可能just schema()方法不适用于jdbc情况。版本可能是问题所在。在2.2.1上测试也可以。这个问题很老了,但如果你对具体的版本感兴趣,我可以查一下。我希望所有2.*都通过属性参数支持自定义模式。我向您投票,所以我们就到此为止。这个周末我会试试。
 "key String, value DECIMAL(20, 0)"