WriteToText仅写入临时文件

时间:2019-07-09 21:17:55

标签: python apache-beam google-cloud-pubsub

我是Apache Beam的新手,它试图用Python编写我的第一个管道,以将来自Google Pub / Sub订阅的数据输出到平面文件中,以供以后使用;理想情况下,我想每半小时将这些批处理成一个文件。我将以下代码作为管道中的最终转换:-

| 'write output' >> WriteToText('TestNewPipeline.txt')

但是,所有创建的文件都位于前缀为“ beam-temp-TestNewPipeline.txt- [somehash]”的目录中,并分成10组,这并不是我所期望的。

我已经尝试过使用window函数,但是它似乎并没有起到什么作用,所以我可能完全误解了这个概念,或者做了完全错误的事情。

该窗口的代码为:-

 | 'Window' >> beam.WindowInto(beam.window.FixedWindows(5))

我认为这将导致文本文件的输出被写入一个静态的5秒窗口中,事实并非如此。

下面的完整代码:-

options = PipelineOptions()
options.view_as(StandardOptions).streaming=True

def format_message(message, timestamp=beam.DoFn.TimestampParam):    
    formatted_message = {
        'data': message.data,
        'attributes': str(message.attributes),
        'timestamp': float(timestamp)
    }

    return formatted_message

with beam.Pipeline(options=options) as p:
    (p
    | 'Read From Pub Sub' >> ReadFromPubSub(subscription='projects/[my proj]/subscriptions/[my subscription]',with_attributes=True)
    | 'Window' >> beam.WindowInto(beam.window.FixedWindows(5))
    | 'Map Message' >> beam.Map(format_message)
    | 'write output' >> WriteToText('TestNewPipeline.txt')
    )
result = p.run()

按预期,该进程将无限期运行并成功读取预订中的消息;但是,它只会将它们写入波束温度文件。有人能帮我指出我要去哪里了吗?

更新:

在Jason发表评论之后,我对管道做了一些修改:-

class AddKeyToDict(beam.DoFn):
    def process(self, element):
        return [(element['rownumber'], element)]

    with beam.Pipeline(options=options) as p:
        (p
        | 'Read From Pub Sub' >> ReadFromPubSub(subscription=known_args.input_subscription)# can't make attributes work as yet! ,with_attributes=True) 
        # failed attempt 1| 'Map Message' >> beam.Map(format_message)
        # failed attempt 2| 'Parse JSON' >> beam.Map(format_message_element)
        | 'Parse to Json' >> beam.Map(lambda x: json.loads(x))
        | 'Add key' >> beam.ParDo(AddKeyToDict())
        | 'Window' >> beam.WindowInto(beam.window.FixedWindows(5), trigger=AfterProcessingTime(15), accumulation_mode=AccumulationMode.DISCARDING)
        | 'Group' >> beam.GroupByKey()
        | 'write output' >> WriteToText(known_args.output_file)
        )

到目前为止,我还无法从PubSub中提取message_id或发布时间,因此我只是使用消息中生成的行号。此时,我仍然只创建临时文件,而最终文件中没有任何内容累积吗?开始怀疑是否仍然缺少Python实现,而我将不得不选择Java。...

2 个答案:

答案 0 :(得分:0)

来自Apache Beam's documentation on Windowing Constraints

  

如果使用Window变换设置窗口功能,则将每个元素分配给一个窗口,但是直到GroupByKeyCombine聚集在窗口和关键点上时,才考虑窗口

由于在此示例中似乎没有键的概念,因此您可以尝试使用Combine吗?

答案 1 :(得分:0)

由于与Apache Beam Python团队合作,Python尚不支持对GCS(或本地文件系统)的流写入,因此为什么不进行流写入?当前仅支持无界目标(例如,大查询表)。

显然,即将发布的Beam for Python v2.14.0版本将支持此功能。