列类型 TIMESTAMP 的 BigQuery 导入转换日期时间偏移量/时区,但列类型 DATETIME 失败并显示“无效的日期时间字符串”

Posted

技术标签:

【中文标题】列类型 TIMESTAMP 的 BigQuery 导入转换日期时间偏移量/时区,但列类型 DATETIME 失败并显示“无效的日期时间字符串”【英文标题】:BigQuery import for column type TIMESTAMP converts datetime offset/timezone, but column type DATETIME fails with `Invalid datetime string` 【发布时间】:2021-07-15 07:30:46 【问题描述】:

当使用 TIMESTAMP 列类型时,BigQuery 似乎采用如下格式

2021-07-14 00:02:30.917983+02:00

(使用 datime.isoformat(sep = ' ') 生成,因为 TIMESTAMP 不支持带 T 分隔符的 iso 格式)

但随后将其转换为 UTC:

2021-07-14 00:04:30.917983 UTC

因为我想要本地时间,所以我尝试创建一个 DATETIME 类型的新列

我正在尝试导入的 JSON:

"load_time_local": "2021-07-15 02:01:02.478638+02:00",
"load_time_local2": "2021-07-15 02:01:02.478638+02:00"

伴随架构:


    "name": "load_time_local",
    "type": "TIMESTAMP",
    "mode": "REQUIRED"
,

    "name": "load_time_local2",
    "type": "DATETIME",
    "mode": "NULLABLE"
,

这会导致错误:

Invalid datetime string "2021-07-15 02:01:02.478638+02:00" Field: load_time_local2;

Big Query 是否支持时区或日期时间偏移?还是我必须去掉偏移量并作为本地时间导入?

如果我想捕获时区信息,我需要两列 utc + 本地时间或本地时间 + 偏移量?

【问题讨论】:

【参考方案1】:

文档对此不是很清楚。

将日期时间数据导入 Big Query 时:

    您不能指定时区 Bigquery 需要 YYYY-MM-DD hh:mm:ss 格式(类似于 ISODate,但使用空格而不是 Tcharacter)。 所有日期时间都必须采用 UTC 格式才能插入。

当您从大查询中查询时,您可以使用时区(事实上,您应该):

select * from `myproject.mydateset.csvimport`
where timestamp_field_0 > '2020-01-01T10:00:00+2'

如果您需要记录此日期时的原始时区(因为需要人工查看),最简单的方法是将时区记录在同一个表中。幸运的是 Bigquery 是一个列式数据库,并且时区信息需要很少的存储空间,因为它会被 bigquery 压缩。

请注意在 BigQuery 中存储正确的时区! 不要存储像“欧洲/马德里”这样的地理时区,因为 BigQuery 将在运行查询时使用与 UTC 的当前偏移量来计算本地时间。 存储适当的时区,如 CET、CEST、EST、EDT 等。

这样你可以在查询过程中轻松转换:

select STRING(utc_timestamp, timezone) from table

【讨论】:

在大多数情况下,我只想从捕获的实际时间查看本地时间的查询结果,而不是当前的夏令时......但那不可能? 这很棘手,因为 DST 的日期每年都在变化 :-( - 除非您将原始时区存储在同一张表的另一列中(BQ 将压缩该数据并且占用的空间很小 - 也许 2每条记录-4 位)- 要将时间戳转换为另一个时区,只需调用STRING( your_datetime_column, "CET" ) (此示例显示中欧时区的日期时间。【参考方案2】:

Big Query 不支持有关日期的时区信息...但 Timestamp 始终应为 UTC,这就是为什么它在导入时接受偏移量,然后将其转换回 UTC。

为了将本地时间输入到 DATETIME 字段中,必须删除时区偏移信息。

使用 python 可以:

berlin = pytz.timezone('Europe/Berlin')
datetime.now(berlin).replace(tzinfo=None).isoformat()

【讨论】:

以上是关于列类型 TIMESTAMP 的 BigQuery 导入转换日期时间偏移量/时区,但列类型 DATETIME 失败并显示“无效的日期时间字符串”的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 字段的类型已从 STRING 更改为 TIMESTAMP

Google Bigquery 的 TIMESTAMP 的 python 数据类型是啥?

BigQuery:无法将 TIMESTAMP_MICROS 类型的字段“stamp”读取为 DATETIME

Google BigQuery日期数据类型?

基于 TIMESTAMP 列的分区的 BigQuery 分区到期

Apache Beam 的 BigQueryIO (Java):无法将 TIMESTAMP 字段写入 BigQuery——fastxml.jackson 异常“类型不支持”