Nifi,CSV到Avro ValidateRecord-将流文件路由到失败,因为字段值中有双引号

时间:2019-12-19 13:59:27

标签: apache-nifi

我正在尝试使用ValidateRecord处理器将CSV验证为Avro。 ValidateRecord处理器的Record Reader属性设置为CSVReader控制器服务。此CSVReader控制器服务的引号字符设置为双引号(“)。

当我尝试验证流文件时,由于字段值中存在双引号,很少有流文件重定向到故障关系。

从流文件内容中采样csv行:

“ ICUA”,“ 01/22/2019”,“ 08:48:18”,394846,“您是否已删除密钥?”,“是---选择“接受回复” >并继续删除“,”,“,”,“ 1”

我想使用ReplaceText,但这会篡改该字段的实际值。

如果有人可以提供应对这种情况的方法,那将真的很有帮助。

谢谢!

2 个答案:

答案 0 :(得分:1)

这不是功能齐全的解决方案。

可能必须扩展正则表达式。所以,这只是一个想法:

尝试对以下参数使用ReplaceText:

search:       ([^,"])"([^,"])
replacement:  $1""$2

enter image description here

答案 1 :(得分:1)

为实现搜索并替换缺失的双引号,我使用了Python等ExecuteScript处理器,

from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from org.apache.nifi.processor.io import StreamCallback
from org.apache.nifi.processors.script import ExecuteScript
from org.python.core.util.FileUtil import wrap
from io import StringIO
import re

# Define a subclass of StreamCallback for use in session.write()
class PyStreamCallback(StreamCallback):
    def __init__(self):
        pass

    def process(self, inputStream, outputStream):
        with wrap(inputStream) as f:
            lines = f.readlines()
            outer_new_value_list = []
            for csv_row in lines:
                field_value_list = csv_row.split('|')
                inner_new_value_list = []
                for field in field_value_list:
                    if field.count('"') > 2:
                        replaced_field = re.sub(r'(?!^|.$)["^]', '""', field)
                        inner_new_value_list.append(replaced_field)

                    else:
                        inner_new_value_list.append(field)
                row = '|'.join([str(elem) for elem in inner_new_value_list])
                outer_new_value_list.append(row)
            with wrap(outputStream, 'w') as filehandle:
                filehandle.writelines("%s" % line for line in outer_new_value_list)
# end class
flowFile = session.get()
if (flowFile != None):
    flowFile = session.write(flowFile, PyStreamCallback())
    session.transfer(flowFile, ExecuteScript.REL_SUCCESS)
# implicit return at the end