datetime - Spark的int96时间类型

标签 datetime apache-spark parquet

当您在 Spark 中创建时间戳列并保存到 parquet 时,您将获得一个 12 字节整数列类型 (int96);我收集的数据分为 6 个字节(儒略日)和 6 个字节(纳秒)。

这不符合任何 Parquet logical type 。那么, Parquet 文件中的架构不会指示该列不是整数。

我的问题是,Spark 如何知道将这样的列加载为时间戳而不是大整数?

最佳答案

语义是根据元数据确定的。我们需要一些进口:

import org.apache.parquet.hadoop.ParquetFileReader
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.hadoop.conf.Configuration

示例数据:

val path = "/tmp/ts"

Seq((1, "2017-03-06 10:00:00")).toDF("id", "ts")
  .withColumn("ts", $"ts".cast("timestamp"))
  .write.mode("overwrite").parquet(path)

和 Hadoop 配置:

val conf = spark.sparkContext.hadoopConfiguration
val fs = FileSystem.get(conf)

现在我们可以访问 Spark 元数据:

ParquetFileReader
  .readAllFootersInParallel(conf, fs.getFileStatus(new Path(path)))
  .get(0)
  .getParquetMetadata
  .getFileMetaData
  .getKeyValueMetaData
  .get("org.apache.spark.sql.parquet.row.metadata")

结果是:

String = {"type":"struct","fields: [
  {"name":"id","type":"integer","nullable":false,"metadata":{}},
  {"name":"ts","type":"timestamp","nullable":true,"metadata":{}}]}

等效信息也可以存储在 Metastore 中。

根据官方文档,这是用来实现与 Hive 和 Impala 的兼容性:

Some Parquet-producing systems, in particular Impala and Hive, store Timestamp into INT96. This flag tells Spark SQL to interpret INT96 data as a timestamp to provide compatibility with these systems.

并且可以使用spark.sql.parquet.int96AsTimestamp属性进行控制。

关于datetime - Spark的int96时间类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42628287/

相关文章:

c# - 忽略毫秒的 LINQ DateTime 查询

scala - 带点 Spark 的列名

apache-spark - 如何在 pyspark 中测试/训练按列值而不是按行分割

apache-spark - 如何在Apache Spark中处理更改 Parquet 架构

python - Pandas 将年份列转换为日期列

c# - 为 IQueryable<T> 生成表达式

python - 将对象转换为日期时间

python - Pyspark rdd : 'RDD' object has no attribute 'flatmap'

azure - HIVE 和 Parquet 文件

hadoop - Spark SQL无法完成大量分片的Parquet数据写入