读取分区镶木地板时,Spark 错误地将以“d”或“f”结尾的分区名称解释为数字

vic*_*orx 5 apache-spark apache-spark-sql pyspark

我用来spark.read.parquet()读取镶木地板文件按分区组织的文件夹。f当分区名称以或结尾时,结果将是错误的d。显然,Spark 会将它们解释为数字而不是字符串。我创建了一个最小的测试用例,如下所示来重现该问题。

df = spark.createDataFrame([
            ('9q', 1),
            ('3k', 2),
            ('6f', 3),
            ('7f', 4),
            ('7d', 5),
     ],
     schema='foo string, id integer'
)
df.write.partitionBy('foo').parquet('./tmp_parquet', mode='overwrite')
read_back_df = spark.read.parquet('./tmp_parquet')
read_back_df.show()
Run Code Online (Sandbox Code Playgroud)

将会read_back_df

+---+---+                                                                       
| id|foo|
+---+---+
|  1| 9q|
|  4|7.0|
|  3|6.0|
|  2| 3k|
|  5|7.0|
+---+---+
Run Code Online (Sandbox Code Playgroud)

注意分区6f/7f/7d变为6.0/7.0/7.0

Spark版本是2.4.3。

wer*_*ner 6

您看到的行为是预期的。

来自Spark 文档

请注意,分区列的数据类型是自动推断的。

spark.sql.sources.partitionColumnTypeInference.enabled您可以通过设置为 False 来禁用此功能。

以下代码在读取 parquet 文件时保留字符串:

spark.conf.set("spark.sql.sources.partitionColumnTypeInference.enabled", False)
read_back_df = spark.read.parquet('./tmp_parquet')
read_back_df.show()
Run Code Online (Sandbox Code Playgroud)

印刷

+---+---+                                                                       
| id|foo|
+---+---+
|  3| 6f|
|  1| 9q|
|  4| 7f|
|  2| 3k|
|  5| 7d|
+---+---+
Run Code Online (Sandbox Code Playgroud)