将 Avro 中存储为整数(自 1970 年 1 月 1 日以来的天数)的“日期”转换为雪花“日期”类型

Posted

技术标签:

【中文标题】将 Avro 中存储为整数(自 1970 年 1 月 1 日以来的天数)的“日期”转换为雪花“日期”类型【英文标题】:Converting 'date' stored as integer (number of days since 1 Jan 1970) in Avro to Snowflake 'date' type 【发布时间】:2020-11-19 16:37:54 【问题描述】:

我需要将数据从一些本地数据库迁移到云端。表中的一些数据以 yyyy-mm-dd 格式存储为“日期”。

我们正在将存储在表中的数据转换为 Avro 格式,然后将其复制到 Snowflake 中。

在 Avro 中,日期存储为整数 Avro Date type

当我尝试将数据推送到雪花中时,它无法将该整数转换回日期。我收到以下错误:'迄今为止无法区分 VARIANT 13707'

其中 13707 是自 1970 年 1 月 1 日以来的天数

谢谢!

【问题讨论】:

日期是否存储在 VARIANT 列中? Snowflake 中定义的列是什么类型,转换是如何完成的?你有例子吗? @Sergui 我尝试作为查询插入:插入 "dbname"."schemaname"."tablename" (start_date) values (to_date(13707)); start_date 的类型为“日期” 【参考方案1】:

您需要根据变量值计算日期值。为此,您可以使用 DATEADD:

https://docs.snowflake.com/en/sql-reference/functions/dateadd.html

create table avro_test ( x date );

insert into avro_test(x) 
select  dateadd('day',parse_json('13707'),'1970-01-01');

select * from avro_test;

+------------+
|     X      |
+------------+
| 2007-07-13 |
+------------+

【讨论】:

【参考方案2】:

如果输入参数的格式是包含整数的字符串:

字符串转换为整数后,整数被视为 Unix 纪元(1970-01-01 00:00:00.000000000 UTC)开始后的秒数、毫秒数、微秒数或纳秒数。

如果整数小于 31536000000(一年中的毫秒数),则将该值视为秒数。

如果该值大于或等于 31536000000 且小于 31536000000000,则该值被视为毫秒。

如果该值大于或等于 31536000000000 且小于 31536000000000000,则该值被视为微秒。

如果该值大于或等于 31536000000000000,则该值被视为纳秒。

如果计算多行(例如,如果输入是包含多于两行的表的列名),则第一个处理的值确定是否将所有后续值视为秒、毫秒、微秒、或纳秒。

如果第一个值大于或等于 31536000000,则所有值都将被视为毫秒,即使某些剩余值小于 31536000000。类似的逻辑适用于微秒和纳秒。

【讨论】:

如果您作为unix时间戳插入,上述逻辑将起作用。但是,如果我尝试插入自纪元开始以来的天数,则不会。

以上是关于将 Avro 中存储为整数(自 1970 年 1 月 1 日以来的天数)的“日期”转换为雪花“日期”类型的主要内容,如果未能解决你的问题,请参考以下文章

Visual C++ 如何将日期时间转换为自 1970 年以来的秒数

为啥mysql中的时间戳范围为1970-2037年?

date详解

date命令

1970 年格式化之前的 Perl 纪元时间

将 unix 时间戳转换为 avro 并将其存储在 BigQuery 中