从 timestamp[us, tz=Etc/UTC] 转换为 timestamp[ns] 会导致时间戳越界

Posted

技术标签:

【中文标题】从 timestamp[us, tz=Etc/UTC] 转换为 timestamp[ns] 会导致时间戳越界【英文标题】:Casting from timestamp[us, tz=Etc/UTC] to timestamp[ns] would result in out of bounds timestamp 【发布时间】:2021-12-29 12:33:22 【问题描述】:

我有一个功能,可以让我从客户端应用程序查询数据块增量表。这是我为此目的使用的代码:

df = spark.sql('SELECT * FROM EmployeeTerritories LIMIT 100')
dataframe = df.toPandas()
dataframe_json = dataframe.to_json(orient='records', force_ascii=False)

但是,第二行给我带来了错误

我知道这个错误是什么意思,我的日期类型字段超出范围,我尝试搜索解决方案,但没有一个符合我的方案。

我找到的解决方案是关于一个特定的数据框列,但在我的情况下,我遇到了一个全局问题,因为我有大量的增量表,而且我不知道具体的日期类型列,所以我可以进行类型操作以便避免这种情况。

是否可以找到所有Timestamp 类型的列并将它们转换为string?这似乎是一个很好的解决方案?您对如何实现我想要做的事情还有其他想法吗?

【问题讨论】:

这能回答你的问题吗? Pyspark toPandas() Out of bounds nanosecond timestamp error 不,它没有。此解决方案要求我知道列名,在我的情况下它不是一个单独的,并且不同的表可能具有不同的列名和时间戳类型。 你不能使用schema 来获取这些列名吗? 【参考方案1】:

是否可以找到所有Timestamp 类型的列并将它们转换为 字符串?

是的,这就是要走的路。您可以遍历df.dtype 并处理具有type = "timestamp" 的列,方法是在调用df.toPandas() 之前将它们转换为字符串:

import pyspark.sql.functions as F

df = df.select(*[
    F.col(c).cast("string").alias(c) if t == "timestamp" else F.col(c)
    for c, t in df.dtypes
])

dataframe = df.toPandas()

您可以将其定义为以df 作为参数的函数,并将其与所有表一起使用:

def stringify_timestamps(df: DataFrame) -> DataFrame:
    return df.select(*[
        F.col(c).cast("string").alias(c) if t == "timestamp" else F.col(c).alias(c)
        for c, t in df.dtypes
    ])

如果要保留时间戳类型,可以考虑将大于pd.Timestamp.max 的时间戳值作废,如post 所示,而不是转换为字符串。

【讨论】:

以上是关于从 timestamp[us, tz=Etc/UTC] 转换为 timestamp[ns] 会导致时间戳越界的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01857 执行 to_timestamp_tz() 时

Oracle DB 中 TO_TIMESTAMP_TZ 和 CAST AS TIMESTAMP WITH LOCAL TIME ZONE 的不同结果

Oracle SQL TO_TIMESTAMP_TZ 格式问题 ORA-01843: not a valid month

Oracle FROM碜TZ函数

将时间戳从 tz='UTC' 更改为 tz='tzutc()'

如何从 UTC 转换为 tzutc() 时区?