0

我们正在将庞大的代码库从 Spark2 迁移到 Spark 3.x。为了逐步进行迁移,一些配置被设置为 legacy 以具有与 Spark 2.x 中相同的行为。功能add_months,但是,AFAIK 没有“传统”模式。根据迁移文档在 Spark3 中

在 Spark 3.0 中,如果原始日期是月份的最后一天,则 add_months 函数不会将结果日期调整为月份的最后一天。例如,选择 add_months(DATE'2019-02-28', 1) 结果 2019-03-28。在 Spark 版本 2.4 及更低版本中,当原始日期是月份的最后一天时,会调整结果日期。例如,将一个月添加到 2019-02-28 会导致 2019-03-31。

而 Spark 2.x 将结果日期调整为该月的最后一天。显而易见的解决方案是围绕它编写一个包装器,但我想知道 Spark3 中是否有任何配置来获得add_months Spark2 行为。

编辑:

我最终在 Scala Spark 3.x 中实现了 add_months 的包装器:

object functions {
  def add_months(startDate: Column, numMonths: Int): Column = add_months(startDate, lit(numMonths))
  def add_months(startDate: Column, numMonths: Column): Column = {
    val addedMonthsSpark   = add_months_spark(startDate, numMonths)
    val startDateIsLastDay = last_day(startDate) === startDate
    when(startDateIsLastDay, last_day(addedMonthsSpark)).otherwise(addedMonthsSpark)
  }
}
4

1 回答 1

0

Here is a Python implementation of the wrapper you mentioned.

def add_months(start_date: str or Column, num_months: int):
    if isinstance(start_date, str):
        start_date = f.col(start_date)

    add_months_spark = f.add_months(start_date, num_months)
    start_date_is_last_day = f.last_day(start_date) == start_date

    return f.when(
        start_date_is_last_day,
        f.last_day(add_months_spark)
    ).otherwise(add_months_spark)

Also, it is possible to avoid using isinstance by utilizing singledispatch in order to overload start_date.

于 2022-01-15T13:39:00.607 回答