U-SQL写入Parquet时DateTime自动转Unix时间戳问题咨询
U-SQL写入Parquet时DateTime转Int64的原因及解决方案
设计原因解析
微软把U-SQL的DateTime转成Int64 Unix时间戳写入Parquet,核心是为了精度兼容和灵活性:
- U-SQL的DateTime类型支持100纳秒级精度(比如你示例里的
2015-05-10T12:15:35.1230000Z,末尾四位是100纳秒单位),但Parquet标准的DateTime类型默认只支持毫秒级精度。如果直接写入标准DateTime,会丢失U-SQL DateTime的高精度部分。 - 用Int64存储100纳秒级的Unix时间戳(从1970-01-01 UTC开始计算),能完整保留原始时间的所有精度信息。同时,这种存储方式让读取工具更灵活:支持高精度的工具可以转回带100纳秒的DateTime,只需要毫秒级的工具也能轻松截断处理。
保留原始DateTime类型的方案
如果需要Parquet文件中存储标准DateTime类型(哪怕牺牲100纳秒精度),可以用以下两种方法:
方法1:手动截断到毫秒级再写入
把U-SQL DateTime转换为毫秒级精度后,Outputters.Parquet就会以标准DateTime类型写入:
SET @@FeaturePreviews = "EnableParquetUdos:on"; @I = SELECT DateTime.FromFileTimeUtc(DateTime.Parse("2015-05-10T12:15:35.1230000Z").ToFileTimeUtc() / 10000 * 10000) AS c_timestamp FROM (VALUES(1)) AS T(x); OUTPUT @I TO @"/data/Test_TimeStamp.parquet" USING Outputters.Parquet();
这里通过ToFileTimeUtc()把时间转为100纳秒单位的数值,除以10000取整再转回,相当于截断到毫秒级,这样写入后Parquet里的c_timestamp就是DateTime类型了。
方法2:自定义Parquet输出UDO(保留高精度)
如果要保留100纳秒精度同时以DateTime类型存储,需要自己写一个自定义输出器:
- 用C#实现继承自
IOutputter的类,在输出逻辑中将U-SQL DateTime转换为Parquet支持的高精度Timestamp类型(比如微秒/纳秒级)。 - 编译DLL并注册到U-SQL环境,然后在脚本中引用这个输出器写入文件。
- 注意:这种方式要求读取Parquet的工具支持高精度Timestamp,否则可能解析出错。
内容的提问来源于stack exchange,提问作者Ca Pham Van
相关产品推荐
相关产品推荐

