无法捕获 Pyspark UDF 异常

Unable to capture Pyspark UDF exception

我正在尝试通过 PysparkUDF 使用 dateparser 解析包含日期字符串的列。

如果解析失败想将空白传递给“date_field”列。

虽然我使用“try-catch”来捕获属性错误,但它不起作用。 即使 except 块最终会低于错误。 AttributeError: 'NoneType' 对象没有属性 'date'

import dateparser

        try:
            parse_date = udf(
                lambda z: dateparser.parse(z).date().strftime("%Y-%m-%d"),
                StringType(),
            )
            build_df = source_df.withColumn(
                "date_field",
                when(col(source_column_name).isNotNull(), to_date(parse_date(col(source_column_name)))).otherwise(" "),
            )
        except  AttributeError:
            build_df = source_df.withColumn("date_field", lit(" "))
        return build_df

两件事:

  1. Spark 使用惰性求值,因此在您调用 .show().collect().toPandas() 之前不会对函数求值。因此整个 try 块执行没有错误,因为 Spark 还没有评估任何东西。只是制定了执行计划。

  2. 要解决此问题,而不是捕获错误,请将您的 lambda 函数替换为

lambda z: dateparser.parse(z).date().strftime("%Y-%m-%d") if z is not None else " "

并替换行

when(col(source_column_name).isNotNull(), to_date(parse_date(col(source_column_name)))).otherwise(" ")

to_date(parse_date(col(source_column_name)))

Spark 的一个已知错误是即使 when 条件为 False 也会计算 UDF,因此请将条件放在 UDF 中。

总体:

parse_date = udf(                
    lambda z: dateparser.parse(z).date().strftime("%Y-%m-%d") if z is not None else " ",
    StringType()
)

build_df = source_df.withColumn(
    "date_field",
     to_date(parse_date(col(source_column_name)))
)