为什么第二次转型失败了?
\ndf\n .withColumn("schemaDetected", schema_of_json(lit("""{"Zipcode":704,"ZipCodeType":"STANDARD","City":"PARC PARQUE","State":"PR"}""")))\n .show(false)\n//shows: struct<City:string,State:string,ZipCodeType:string,Zipcode:bigint>\n\ndf\n .withColumn("literal", lit("""{"Zipcode":704,"ZipCodeType":"STANDARD","City":"PARC PARQUE","State":"PR"}"""))\n .withColumn("schemaDetected", schema_of_json(col("literal")))\n .show(false)\n// it fails:\n// cannot resolve 'schema_of_json(`literal`)' due to data type mismatch: The input json should be a string literal and not null; however, got `literal`.;;\nRun Code Online (Sandbox Code Playgroud)\n我需要获取一个列模式,但它只接受方法内部包含的“lit”,当我添加列时它会失败。\xc2\xbf为什么?
\n第二个转换失败,因为当您将包含 json 字符串的列从数据帧传递到schema_of_json函数 Spark 时,无法确定该列的每一行 json 字符串将计算为相同的架构
要理解为什么所有行具有相同的架构很重要,您必须承认创建schema_of_json函数的主要用例是推断from_json函数的架构。
from_json将 json 字符串转换为struct,基本上是几个新列。当然,数据框中的所有行都应该具有相同的列。因此,您必须确保from_json在数据帧上使用时,将相同的架构传递给所有行。
在原点,您应该能够传递不是literalto的列,如您在票证SPARK-24642schema_of_json中看到的那样。然而,这意味着合并每一行的推断模式。例如,如果您有以下数据框:
+------------------+
| json_string |
+------------------+
| {"a": 1} |
| {"b": 2} |
| {"a": 3, "c": 4} |
+------------------+
Run Code Online (Sandbox Code Playgroud)
并且您想要将返回的模式传递给schema_of_json函数from_json,您必须推断模式STRUCT<a INT, b INT, c INT>才能为所有行提供一致的模式。为此,您需要转换schema_of_json为聚合函数,该函数将通过迭代参数列的所有值来构建架构或进行架构推断(就像读取 CSV 时一样)。被认为不值得。
因此,您不能传递数据帧列作为参数,而只能传递literal,您可以使用SPARK-24709lit中实现的函数来获取它
schema_of_json后来在 Spark 3.1 中进行了升级(请参阅SPARK-31044),以便能够采用可折叠列,这意味着可以在查询执行之前静态评估列。这种可折叠柱的一个例子是regexp_replace(lit("""{"test":1}""", "1", "2")),它不是直接的,literal而是一个literal
因此,回到您的案例,当您从 中创建列时lit(...),Spark 会看到该列,但看不到其内容。由于 Spark 看不到列的内容,因此无法确定该列的值是否相同。但 Spark 必须确保这些值生成的模式相同,因此它必须确保输入值相同。所以它会抛出一个错误,基本上说“我不能确定对于所有行,此列中包含的 json 字符串都是相同的”
| 归档时间: |
|
| 查看次数: |
1536 次 |
| 最近记录: |