You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark读取PyArrow写入的Pandas Parquet报INT64时间戳错误求解决

解决PySpark读取Pandas+PyArrow写入的Parquet文件时报"Illegal Parquet type: INT64 (TIMESTAMP(NANOS,false))"的问题

问题原因

Pandas通过PyArrow写入Parquet时,会将timestamp类型以纳秒精度的INT64格式存储;而Spark默认的Parquet Reader对这种类型的解析存在兼容性问题,即使是3.4.x/3.5.x版本也需要额外配置才能支持。

无需修改Parquet文件的解决方案

方案1:开启Spark对纳秒时间戳的支持(推荐,适用于Spark 3.3+)

在创建SparkSession时添加相关配置,让Spark能够识别纳秒精度的timestamp类型:

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("ReadNanoTimestampParquet") \
    .config("spark.sql.parquet.timestampNanosEnabled", "true") \
    .config("spark.sql.timestampType", "TIMESTAMP_NTZ")  # TIMESTAMP_NTZ表示无时区,根据实际需求选择TIMESTAMP_LTZ(带时区)
    .getOrCreate()

# 正常读取文件
spark_df = spark.read.parquet('data/tests_dataset')

配置说明:

  • spark.sql.parquet.timestampNanosEnabled=true:允许Spark解析存储为INT64的纳秒精度timestamp
  • spark.sql.timestampType:指定Spark内部使用的timestamp类型,根据原数据是否带时区选择对应值

方案2:手动转换类型(适用于所有Spark版本)

如果无法升级Spark版本或配置不生效,可以先将timestamp列当作长整型读取,再手动转换为timestamp类型:

  1. 定义自定义Schema,将timestamp列指定为LongType
  2. 读取文件后,将长整型值转换为timestamp(纳秒转timestamp需除以1e9)

示例代码:

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, LongType, TimestampType, StringType

# 自定义Schema,替换为你的实际列结构
custom_schema = StructType([
    StructField("id", StringType(), nullable=True),
    StructField("event_time", LongType(), nullable=True),
    # 其他列按实际情况添加
])

spark = SparkSession.builder.appName("ReadParquetManualConvert").getOrCreate()

# 按自定义Schema读取
raw_df = spark.read.schema(custom_schema).parquet('data/tests_dataset')

# 将纳秒级长整型转换为timestamp
converted_df = raw_df.withColumn("event_time", (raw_df["event_time"] / 1e9).cast(TimestampType()))

注意:如果你的Spark版本低于3.2,timestamp仅支持微秒精度,此时需将除以1e9改为除以1e6,并取整,会丢失纳秒部分的精度。

内容的提问来源于stack exchange,提问作者Stefano Castoldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:52:44