微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 ExecuteSQLRecord 和 CSVRecordSetWriter 更新日期时间值的时区?

如何解决为什么 ExecuteSQLRecord 和 CSVRecordSetWriter 更新日期时间值的时区?

我是 NiFi 的新手。我希望这里有人可以就我的时区问题向我提出建议。我有这些处理器:

ListDatabaseTables -> GenerateTableFetch -> ExecutesqlRecord(通过 CSVRecordWriter 写入 csv 文件)-> ... ... Putsql(使用 Load Data 命令将 csv 文件加载到 MysqL

数据库是 Oracle。 CSVRecordWriter 具有以下属性

public static string JsonPrettify(this string json)
{
    if (string.IsNullOrEmpty(json))
    {
        return json;
    }

    using (var stringReader = new StringReader(json))
    using (var stringWriter = new StringWriter())
    {
        var jsonReader = new JsonTextReader(stringReader);
        var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
        jsonWriter.Writetoken(jsonReader);
        return stringWriter.ToString();
    }
}

我的源数据库和目标数据库都在美国东部时区。但是,我注意到 ExecutesqlRecord 的输出将时间值转换为 UTC(增加到 5 小时)。这会导致目标数据库中的时间值错误。可能有一些方法可以单独转换每个日期/时间列,但这将需要大量的开发工作。

有没有办法在全局级别或至少在表级别正确处理这个问题?请注意,时间格式需要为 MysqL 负载数据所接受。

先谢谢你!

解决方法

NiFi 使用绝对时间值(基于 UTC),仅当值需要以文本格式(CSV、JSON、XML 等)表示时,才将值转换为字符串时间戳并使用 ISO 8601 格式,表示时区(如果不是 UTC)显示在字符串中。

然而,MySQL 需要数据库主机时区中的所有时间戳(文字和值)(请参阅 here)并且不接受时区值 (in a literal for example)。从技术上讲,您需要通过将 UTC 值视为确实在目标时区中来处理时间值来更改时间值(例如从值中减去 5 小时)。

我认为您需要使用 ExecuteSQLRecord 的 SQL Pre-Query 属性为源数据库 set the timezone of the session。如果这会使时间戳值看起来像是在目标数据库时区中的效果,那么 MySQL 应该负责其余的工作。如果这不起作用,您可能需要使用 UpdateRecord 或脚本处理器从时间戳值中手动减去 5 小时。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。