ApacheNIFI:如何比较csv中的多行并创建新列
我有一个csv,看起来像这样ApacheNIFI:如何比较csv中的多行并创建新列,csv,apache-nifi,Csv,Apache Nifi,我有一个csv,看起来像这样 Jc,TXF,timer,alpha,beta 15,44,55,12,33 18,87,33,111 9,87,61,29,77 Alpha和Beta组合构成一个城市代码。我想将城市名称作为新列添加到csv中 Jc,TXF,timer,alpha,beta,city 15,44,55,12,33,York 18,87,33,111,London 9,87,61,29,77,Sydney 我有另一个csv,只有列alpha、beta、city。看起来是这样的:
Jc,TXF,timer,alpha,beta
15,44,55,12,33
18,87,33,111
9,87,61,29,77
Alpha和Beta组合构成一个城市代码。我想将城市名称作为新列添加到csv中
Jc,TXF,timer,alpha,beta,city
15,44,55,12,33,York
18,87,33,111,London
9,87,61,29,77,Sydney
我有另一个csv,只有列alpha、beta、city
。看起来是这样的:
alpha,beta,city
12,33,York
33,111,London
29,77,Sydney
如何使用ApacheNIFI实现这一点。请建议实现此目标所需的处理器和工作流程。我认为有两种方法可以解决此问题 首先使用
CsvLookupService
。但是,CsvLookupService
只支持一个键,但是您有两个键,alpha键和beta键。因此,要使用这个解决方案,您必须将两个键连接成一个键,如12_33
其次,使用ExecuteScript
处理器。这个更好,因为您不必修改源数据。战略:
标题行计数设置为1,以将标题行包括在拆分内容中。对于ExecuteScript
处理器,将python设置为脚本引擎
,并提供以下脚本正文
:
from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from org.apache.nifi.processor.io import StreamCallback
import csv
# Define a subclass of StreamCallback for use in session.write()
class PyStreamCallback(StreamCallback):
def __init__(self):
pass
def process(self, inputStream, outputStream):
# fetch the mapping CSV file
with open('/home/nifi/mapping.csv', 'r') as mapping:
# read the mapping file
mappingContent = csv.reader(mapping, delimiter=',')
# flowfile content is CSV text with two lines, header and actual content
# split by newline to get access to each inidvidual line
lines = IOUtils.toString(inputStream, StandardCharsets.UTF_8).split('\n')
# the result will contain the header line
# the result will have the additional city column
result = lines[0] + ',city\n'
# take the second line and split it
# to get access to alpha, beta and city values
lineSplit = lines[1].split(',')
# Go through the mapping file
# item[0] -> alpha
# item[1] -> beta
# item[2] -> city
# See if you find alpha and beta on the line content
for item in mappingContent:
if item[0] == lineSplit[3] and item[1] == lineSplit[4]:
result += lines[1] + ',' + item[2]
break
if result is None:
raise Exception('No matching found.')
else:
outputStream.write(bytearray(result.encode('utf-8')))
# end class
flowFile = session.get()
if(flowFile != None):
try:
flowFile = session.write(flowFile, PyStreamCallback())
session.transfer(flowFile, REL_SUCCESS)
except Exception as e:
session.transfer(flowFile, REL_FAILURE)
有关脚本的详细说明,请参见注释<代码>/home/nifi/mapping.csv
必须在nifi实例上可用。如果要了解有关ExecuteScript
处理器的更多信息,请参阅。最后,将所有行合并到一个CSV文件中:
设置CSV读写器。保留其默认属性。调整MergeContent
属性以控制每个生成的CSV文件中应有多少行。结果:
您必须使用LookupRecord。然而,CsvLookupService只支持一个密钥,但您有两个密钥,alpha和beta。如果您只有一个键,例如alpha键和beta键像这样连接起来会容易得多:12_33@Upvote然后我将不得不连接两个csv,以便以这种方式进行比较,我认为这将占用大量资源。然而,如果您能在使用上述技术的同时提出一个答案,我们将不胜感激。