You need to enable JavaScript to run this app. Dask日期列存储为Parquet后Apache Drill查询返回微秒时间戳问题
优惠活动
大模型
产品
解决方案
定价
更多

Dask日期列存储为Parquet后Apache Drill查询返回微秒时间戳问题

Dask存储Parquet日期列类型异常的解决方法

问题背景

  • 基于含日期列、数值列的Dask DataFrame,执行如下代码写入Parquet存储:
ddf.to_parquet('/some/folder', engine='pyarrow', overwrite=True)
  • 预期效果:日期列以Parquet原生日期类型写入,查询时可直接得到格式化的年月日值
  • 实际现象:使用Apache Drill查询时,日期列返回16位微秒级时间戳数值,对应关系如下:
    • 数值1546300800000000 对应实际期望日期2019-01-01
    • 数值1548979200000000 对应实际期望日期2019-02-01
  • 已尝试在Drill中使用CAST语句将数值转换为日期格式,未得到预期结果
  • 待解决问题:
    1. 是否存在配置项可指定Dask将日期列以原生日期类型写入Parquet
    2. 如何通过Apache Drill查询获取正确的格式化日期结果

解决方案

1. Dask端修正写入的Parquet日期类型

出现微秒时间戳存储的核心原因:Dask搭配pyarrow引擎写入时,默认会将datetime64类型列映射为timestamp[us](微秒级时间戳)类型,而非Parquet规范定义的原生DATE类型,可通过显式指定schema强制类型映射:

  • 写入前先对日期列做类型预处理,剥离时分秒信息,切换为pyarrow的原生日期类型
  • 调用to_parquet时通过schema参数显式声明列类型,示例代码:
import pyarrow as pa

# 预处理日期列,转为pyarrow原生日期类型
ddf['date_col'] = ddf['date_col'].dt.date.astype('date32[pyarrow]')

# 写入时指定schema,强制日期列为Parquet原生DATE类型
ddf.to_parquet(
    '/some/folder',
    engine='pyarrow',
    overwrite=True,
    schema=pa.schema([
        ('date_col', pa.date32()),
        ('value_col', pa.float64())  # 按实际数值列类型调整
    ])
)
  • 完成上述配置后,Parquet文件中的日期列会以原生DATE类型存储,不再以微秒时间戳形式落盘

2. Apache Drill端转换微秒时间戳为日期格式

针对已经生成的微秒时间戳存储的Parquet文件,无需重新生成文件,可在查询时通过内置函数完成转换,之前CAST转换失败的原因是未对齐时间戳单位,直接将微秒值按秒级epoch传入转换函数,导致结果异常:

  • 转换逻辑:先将微秒级时间戳除以1000000,换算为秒级epoch时间,再通过时间转换函数生成目标日期
  • 字符串格式日期查询示例:
SELECT
  FROM_UNIXTIME(date_col / 1000000, 'yyyy-MM-dd') AS formatted_date,
  value_col
FROM dfs.`/some/folder`
  • 原生DATE类型结果查询示例(返回值为日期类型而非字符串):
SELECT
  CAST(TO_TIMESTAMP(date_col / 1000000) AS DATE) AS date_value,
  value_col
FROM dfs.`/some/folder`
  • 结果校验:
    • 代入值1546300800000000,换算后秒级epoch为1546300800,转换后正好得到2019-01-01
    • 代入值1548979200000000,换算后秒级epoch为1548979200,转换后正好得到2019-02-01

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 20:27:03