读取分区镶木地板时,Spark 错误地将以“d”或“f”结尾的分区名称解释为数字
Posted
技术标签:
【中文标题】读取分区镶木地板时,Spark 错误地将以“d”或“f”结尾的分区名称解释为数字【英文标题】:Spark incorrectly interpret partition name ending with 'd' or 'f' as number when reading partitioned parquets 【发布时间】:2020-07-01 07:26:07 【问题描述】:我正在使用spark.read.parquet()
从分区中组织 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()
read_back_df
将是
+---+---+
| id|foo|
+---+---+
| 1| 9q|
| 4|7.0|
| 3|6.0|
| 2| 3k|
| 5|7.0|
+---+---+
注意分区6f/7f/7d
变成6.0/7.0/7.0
。
spark 版本是 2.4.3。
【问题讨论】:
【参考方案1】:您看到的行为是预期的。
来自Spark documentation:
请注意,分区列的数据类型是自动推断的。
您可以通过将 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()
打印
+---+---+
| id|foo|
+---+---+
| 3| 6f|
| 1| 9q|
| 4| 7f|
| 2| 3k|
| 5| 7d|
+---+---+
【讨论】:
感谢您的回答。上述设置的更改确实有效。但是,我觉得还有一个问题没有解决。为什么像 6f 或 7f 这样的值会被推断为浮点数?这不奇怪吗? 看看this code。 Spark 只需获取文件夹的名称并尝试解析名称。 6f 是浮点数的有效表达式。以上是关于读取分区镶木地板时,Spark 错误地将以“d”或“f”结尾的分区名称解释为数字的主要内容,如果未能解决你的问题,请参考以下文章
读取镶木地板文件时,有没有办法在 basePath 中使用通配符?
Apache Spark 数据帧在写入镶木地板时不会重新分区