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

Apache nifi 为什么ExecuteSQLRecord和CSVRecordSetWriter更新了日期时间值的时区?,apache-nifi,Apache Nifi,我是NiFi的新手。我希望这里有人能就我的时区问题给我建议。我有这些处理器: ListDatabaseTables->GenerateTableFetch->ExecuteSQLRecord(由CSVRecordWriter写入csv文件)->。。。PutSQL(使用Load Data命令将csv文件加载到MySQL) 源数据库是Oracle。CSVRecordWriter具有以下属性: Schema Write Strategy -> Do Not Write Schema Schema

我是NiFi的新手。我希望这里有人能就我的时区问题给我建议。我有这些处理器:

ListDatabaseTables->GenerateTableFetch->ExecuteSQLRecord(由CSVRecordWriter写入csv文件)->。。。PutSQL(使用Load Data命令将csv文件加载到MySQL)

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

Schema Write Strategy -> Do Not Write Schema
Schema Access Strategy -> Inherit Record Schema
Schema Name -> ${schema.name}
Schema Text -> ${avro.schema}
Date Format -> yyyy-MM-dd
Time Format -> HH:mm:ss
Timestamp Format -> yyyy-MM-dd HH:mm:ss
我的源数据库和目标数据库都位于美国东部时区。但是,我注意到ExecuteSQLRecord的输出将时间值转换为UTC(增加到5小时)。这将导致目标数据库中的时间值错误。可能有一些方法可以单独转换每个日期/时间列,但这将需要大量的开发工作

是否有一种方法可以在全局级别或至少在表级别正确处理此问题?请注意,MySQL加载数据需要接受时间格式


提前谢谢你

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

但是,MySQL需要数据库主机时区中的所有时间戳(文本和值)(请参阅),不接受时区值()。从技术上讲,您需要通过将UTC值视为确实在目标时区来更改时间值(例如,从该值中减去5小时)

我认为您需要使用ExecuteSQLRecord的
sqlpre-Query
属性为源数据库创建一个查询。如果这会使时间戳值看起来像在目标DB时区中,那么MySQL应该处理其余的部分。如果不起作用,您可能需要使用UpdateRecord或脚本处理器从时间戳值中手动减去5小时。

谢谢。 我尝试为Oracle设置会话时区。它不起作用

通过使用以下查询生成下一步要执行的另一个查询,我找到了一个解决方法。此查询将Oracle日期值转换为全局级别的首选字符串,从而节省列级别或表级别的开发工作量

挑选 利斯塔格( 列ID=1时的大小写,然后“选择”数据输入时的大小写(“日期”,“时间戳”),然后“到字符”(“| |列名称”,“YYYY-MM-DD HH24:MI:SS”)作为“| |列名称” ELSE列名称结束 否则,当数据键入('DATE','TIMESTAMP'),然后将“TO_CHAR”('| | COLUMN| | |','YYYY-MM-DD HH24:MI:SS'')作为“| | COLUMN| |” ELSE列名称结束 结束 组内(按列ID排序) ||'从'||'${db.table.name}'作为我的_记录
从用户选项卡列 其中table_name='${db.table.name}'
;

感谢您澄清基于NiFi文本的编写器隐式地将所有db日期(在本例中为oracle)转换为UTC。但似乎在转换为UTC时存在错误,有些日期转换为夏令时,有些日期转换为非夏令时。例如,对于日期分别为99年12月31日13:00:00和19年4月30日14:00:00的同一源表(基于澳大利亚/悉尼tz),流文件中的csv值分别为99年12月31日02:00:00和19年4月30日04:00:00,相差+11:00和+10:00小时。UTC转换在同一个流文件中不一致。