我仍然是Apache Beam / Cloud Dataflow的新手,所以如果我的理解不正确,我会道歉。
我正在尝试通过管道读取大约30,000行的数据文件。我的简单管道首先从GCS打开csv,从数据中取出标头,通过ParDo / DoFn函数运行数据,然后将所有输出写入csv回GCS。这条管道起了作用,是我的第一次测试。
然后我编辑了管道来读取csv,拔出标题,从数据中删除标题,通过ParDo / DoFn函数运行数据,标题作为侧输入,然后将所有输出写入一个csv。唯一的新代码是将标头作为侧输入传递并从数据中过滤它。
ParDo / DoFn函数build_rows只生成了context.element,这样我就可以确保我的边输入正常工作。
我得到的错误如下:
我不确定问题是什么,但我认为这可能是由于内存限制。我将样本数据从30,000行减少到100行,我的代码终于工作了。
没有侧输入的管道会读/写所有30,000行,但最后我需要侧输入来对我的数据进行转换。
如何修复我的管道以便我可以从GCS处理大型csv文件并仍然使用侧输入作为文件的伪全局变量?
答案 0 :(得分:2)
我最近为Apache Beam编写了CSV file source,我已将其添加到beam_utils
PiPy包中。具体来说,您可以按如下方式使用它:
pip install beam_utils
from beam_utils.sources import CsvFileSource
。beam.io.Read(CsvFileSource(input_file))
。在默认行为中,CsvFileSource
返回由标头索引的字典 - 但您可以查看文档以确定您要使用的选项。
另外,如果你想实现自己的自定义CsvFileSource
,你需要继承梁的FileBasedSource
:
import csv
class CsvFileSource(beam.io.filebasedsource.FileBasedSource):
def read_records(self, file_name, range_tracker):
self._file = self.open_file(file_name)
reader = csv.reader(self._file)
for i, rec in enumerate(reader):
yield res
您可以扩展此逻辑以解析标头和其他特殊行为。
另外,作为一个注释,这个源不能拆分,因为它需要被顺序解析,所以它可能代表处理数据时的瓶颈(尽管可能没问题)。