我们正试图提取约。来自数据库的40 GB数据,并希望生成多个csv文件。我们以流式方式使用mule DB连接器,它返回'ResultSetIterator'
Q1)如何将此ResultSetIterator
转换为arraylist?或我们可以进一步用于生成文件的任何可读格式
Q2)我们尝试使用For-Each组件将这些数据拆分成块,它用于有限的数据集和用于提供SerializationException
的大量数据
在下面的输入摘录中,我们使用for-each制作数据块并将其提供给多个文件的批处理
<batch:job name="testBatchWithDBOutside">
<batch:input>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step">
<batch:commit size="10" doc:name="Batch Commit">
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<file:outbound-endpoint path="C:\output" outputPattern="#[message.id].txt" responseTimeout="10000" doc:name="File"/>
</batch:commit>
</batch:step>
</batch:process-records>
</batch:job>
<flow name="testBatchWithDBOutsideFlow" processingStrategy="synchronous">
<file:inbound-endpoint path="C:\input" responseTimeout="10000" doc:name="File"/>
<db:select config-ref="MySQL_Configuration" streaming="true" fetchSize="10" doc:name="Database">
<db:parameterized-query><![CDATA[select * from classicmodels]]></db:parameterized-query>
</db:select>
<foreach batchSize="5" doc:name="For Each">
<batch:execute name="testBatchWithDBOutside" doc:name="testBatchWithDBOutside"/>
</foreach>
</flow>
答案 0 :(得分:0)
Q1。您不希望将Iterator转换为List,因为这会破坏从DB连接器流式传输的目的并将所有记录加载到内存中。无论如何,Mule以相同的方式处理迭代器和列表。
Q2。批处理模块意味着for-each操作。 batch的输出:input必须是List或Iterator。你应该能够简化这个
<batch:job name="testBatch">
<batch:input>
<db:select config-ref="MySQL_Configuration" streaming="true" fetchSize="10" doc:name="Database">
<db:parameterized-query><![CDATA[select * from classicmodels]]></db:parameterized-query>
</db:select>
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step">
<object-to-string-transformer doc:name="Object to String"/>
<file:outbound-endpoint path="C:\output" outputPattern="#[message.id].txt" responseTimeout="10000" doc:name="File"/>
</batch:step>
</batch:process-records>
</batch:job>
您还需要使用转换数据库记录的组件替换object-to-string-transformer(此时的有效负载将是一个映射,其中键是列名,值是记录值)进入csv线。
您可以在Mule博客中找到一个不错的例子:https://blogs.mulesoft.com/dev/anypoint-platform-dev/batch-module-reloaded/
另一个选择是删除批处理器并使用DataWeave生成csv输出并将其流式传输到文件。这可能会有所帮助:https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-streaming
Dataweave会在处理每条记录时调用ResultSetIterator上的next,并且Iterator将处理从底层数据库中选择记录块,因此步骤之间没有排队,或者将完整数据集加载到内存中。
<flow name="batchtestFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/batch" allowedMethods="GET" doc:name="HTTP"/>
<db:select config-ref="Generic_Database_Configuration" streaming="true" doc:name="Database">
<db:parameterized-query><![CDATA[select * from Employees]]></db:parameterized-query>
</db:select>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%input payload application/java
%output application/csv streaming=true, header=true, quoteValues=true
---
payload map ((e, i) -> {
surname: e.SURNAME,
firstname: e.FIRST_NAME
})]]></dw:set-payload>
</dw:transform-message>
<file:outbound-endpoint path="C:/tmp" outputPattern="testbatchfile.csv" connector-ref="File" responseTimeout="10000" doc:name="File"/>
</flow>
答案 1 :(得分:0)
您想使用OutputHander。确保你打开了流媒体然后使用脚本组件,例如选择groovy并一次处理一行,如下所示:
// script.groovy
return {evt, out ->
payload.each { row ->
out << row.SOMECOLUMN.... }
} as OutputHandler
xml中的组件
<scripting:transformer returnClass="TODO" doc:name="ScriptComponent">
<scripting:script engine="Groovy" file="script.groovy" />
</scripting:transformer>
如果要返回一些输出。但是,如果您要在您的情况下写入文件,则不会使用变量out
,而是写入您的文件。
答案 2 :(得分:0)
我找到了一种简单快捷的方法,如下所示:
此处DB连接器处于流式传输模式,For-Each正在按给定的批量大小
拆分记录<flow name="testFlow" processingStrategy="synchronous">
<composite-source doc:name="Composite Source">
<quartz:inbound-endpoint jobName="test" cronExpression="0 48 13 1/1 * ? *" repeatInterval="0" connector-ref="Quartz" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job/>
</quartz:inbound-endpoint>
<http:listener config-ref="HTTP_Listener_Configuration" path="/hit" doc:name="HTTP"/>
</composite-source>
<db:select config-ref="MySQL_Configuration" streaming="true" fetchSize="10000" doc:name="Database">
<db:parameterized-query><![CDATA[SELECT * FROM tblName]]></db:parameterized-query>
</db:select>
<foreach batchSize="10000" doc:name="For Each">
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/csv
---
payload map {
field1:$.InterfaceId,
field2:$.Component
}]]></dw:set-payload>
</dw:transform-message>
<file:outbound-endpoint path="F:\output" outputPattern="#[message.id].csv" responseTimeout="10000" doc:name="File"/>
</foreach>
<set-payload value="*** Success ***" doc:name="Set Payload"/>
</flow>