下面是我的代码
val query = """
(select id, data as b_data from gtest) t
"""
val df = spark.read.format("jdbc")
.option("url", "jdbc:mysql://192.168.0.22:3306/db")
.option("driver", "com.mysql.jdbc.Driver")
.option("useSSL", "false")
.option("user", "dba")
.option("password", "pwd")
.option("dbtable",query)
.load()
df.createOrReplaceTempView("tbl")
在mysql表tbl中的字段b_data是varchar类型的,并且具有如下所示的JSON (只是一个示例),它可以被嵌套,我希望能够使用这个JSON,而不必使用固定的模式,因为手动定义模式是不切实际的,因为JSON可以是大的和嵌套的。
{"id" : 100, "details" : {"fn" : "sample", "ln" : "data"}}
我希望能够做到以下几点
%sql
select id, b_data.id, b_data.details.fn from tbl
一些信息
df.printSchema
root
|-- id: integer (nullable = true)
|-- b_data: string (nullable = true)
spark.version
res89: String = 2.4.5
当我运行sql查询时得到的异常如下
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
....
....
....
Caused by: org.apache.spark.sql.AnalysisException: Can't extract value from b_data#4270: need struct type but got string; line 1 pos 10
at org.apache.spark.sql.catalyst.expressions.ExtractValue$.apply(complexTypeExtractors.scala:73)
......
我假设DataFrame的列类型必须从String更改为DataStruct??我在这一点上迷失了方向。
发布于 2020-04-29 15:18:45
可能b_data
的数据类型是字符串(JSON string),所以您无法对其进行查询。在创建临时视图之前,您可能需要读取json字符串。
您可以在阅读时提供自定义模式,也可以使用schema_of_json
函数获取模式
val schema = schema_of_json(lit(df.select($"b_data").as[String].first))
val resultDF = df.withColumn("b_data_new", from_json($"b_data", schema))
resultDF.createOrReplaceTempView("tbl")
现在您可以按如下方式查询
select b_data_new.id, b_data_new.details.fn from tbl
https://stackoverflow.com/questions/61495225
复制相似问题