java—在使用sparkDataframe的配置单元分区中缺少日期的前导零

2nbm6dog  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(400)

我正在向sparkDataframe添加一个分区列。新列包含年月日。我的Dataframe中有一个timestamp列。

DataFrame dfPartition = df.withColumn("year", df.col("date").substr(0, 4));
dfPartition = dfPartition.withColumn("month", dfPartition.col("date").substr(6, 2));
dfPartition =  dfPartition.withColumn("day", dfPartition.col("date").substr(9, 2));

我可以在输出Dataframe时看到正确的列值,例如: 2016 01 08 但是当我将这个Dataframe导出到配置单元表时

dfPartition.write().partitionBy("year", "month","day").mode(SaveMode.Append).saveAsTable("testdb.testtable");

我看到目录结构生成了前导零的未命中。我试着把柱子串起来,但没有成功。
有没有办法在配置单元分区中捕获两位数的日期/月份
谢谢

pdtvr36n

pdtvr36n1#

请参阅向spark数据框中的列添加前导零
您可以看到如何使用以下答案添加前导0的答案:

val df2 = df
        .withColumn("month", format_string("%02d", $"month"))

我用下面的代码片段在我的代码中尝试了这个,它成功了!

.withColumn("year", year(col("my_time")))
            .withColumn("month", format_string("%02d",month(col("my_time")))) //pad with leading 0's
            .withColumn("day", format_string("%02d",dayofmonth(col("my_time")))) //pad with leading 0's
            .withColumn("hour", format_string("%02d",hour(col("my_time")))) //pad with leading 0's
            .writeStream
            .partitionBy("year", "month", "day", "hour")
sf6xfgos

sf6xfgos2#

根据spark文档,分区列类型推断是默认启用的功能。op字符串值,因为它们可以解释为int,所以被转换为int。如果这在整个spark会话中是不需要的,可以通过将相应的spark配置属性设置为 false :

SparkSession.builder.config("spark.sql.sources.partitionColumnTypeInference.enabled", value = false)

或者运行相应的 SET key=value 使用sql的命令。否则,可以在列级别单独抵消它,并使用j.doe建议的相应spark原生格式字符串函数。

相关问题