Spark代码报错TypeError:datetime.date与str无法做减法,请求修复
错误原因与修复方案
核心错误点
TypeError源于类型不匹配:end_date_str是从Spark DataFrame collect后得到的datetime.date对象,而start_date_str是原始字符串,两者无法直接用-运算。- 额外两处逻辑错误:
add_months(start_date_str, 12 * 10):add_months函数要求输入是Spark日期列,不能直接传字符串。date_add(lit(start_date_str), col("id").cast("date")):date_add的第二个参数是天数(整数),把id转成date类型完全错误。
修复后的完整代码
from pyspark.sql.functions import * from datetime import datetime # 获取输入的起始日期字符串 start_date_str = dbutils.widgets.get("startdate") # 转换为Spark日期列 start_date = to_date(lit(start_date_str), 'yyyy-MM-dd') # 计算10年后的结束日期(用Spark函数处理,避免本地转换) end_date = add_months(start_date, 12 * 10) # 计算日期总天数差(用Spark函数在分布式环境计算,更高效) days_diff = (spark .range(1) .select(datediff(end_date, start_date).alias("diff")) .collect()[0]["diff"]) # 生成日期范围:用id作为天数偏移,转换为整数 date_range = spark.range(0, days_diff, 1) \ .withColumn("date", date_add(lit(start_date_str), col("id").cast("int"))) # 构建时间维度表 dim_time = date_range \ .withColumn("day_of_week", date_format(col("date"), "EEEE")) \ .withColumn("current_day", when(col("date") == current_date(), 1).otherwise(0)) \ .withColumn("working_day", when(col("day_of_week").isin(["Saturday", "Sunday"]), 0).otherwise(1)) \ .withColumn("month_id", month(col("date")).cast("smallint")) \ .withColumn("month_desc", date_format(col("date"), "MMM")) \ .withColumn("quarter_id", quarter(col("date")).cast("smallint")) \ .withColumn("quarter_desc", concat(lit("Q"), quarter(col("date")).cast("string"))) \ .withColumn("year", year(col("date")).cast("smallint")) \ .select("date", "day_of_week", "current_day", "working_day", "month_id", "month_desc", "quarter_id", "quarter_desc", "year")
关键修复说明
- 日期运算类型统一:用
datediff函数直接计算两个Spark日期列的天数差,避免将日期对象拉到本地后和字符串运算。 - 修正
add_months参数:传入转换后的start_date(Spark日期列)而非原始字符串。 - 修正
date_add的偏移量类型:将id转换为int类型,符合date_add对天数参数的要求。 - 移除无效代码:删除了未使用的
end_date变量的错误赋值行。
内容的提问来源于stack exchange,提问作者Abinandhana G
相关产品推荐
相关产品推荐

