Python WriteToText仅写入临时文件

Python WriteToText仅写入临时文件,python,apache-beam,google-cloud-pubsub,Python,Apache Beam,Google Cloud Pubsub,我不熟悉ApacheBeam,正试图用Python编写我的第一条管道,以便将来自Google发布/订阅的数据输出到平面文件,供以后使用;理想情况下,我希望将这些文件成批处理,例如每半小时一次。我将以下代码作为管道中的最终转换:- |“写入输出”>>WriteToText('TestNewPipeline.txt')) 但是,创建的所有文件都位于一个前缀为“beam temp TestNewPipeline.txt-[somehash]”的目录中,并被分成10组,这不是我所期望的 我尝试过使用窗

我不熟悉ApacheBeam,正试图用Python编写我的第一条管道,以便将来自Google发布/订阅的数据输出到平面文件,供以后使用;理想情况下,我希望将这些文件成批处理,例如每半小时一次。我将以下代码作为管道中的最终转换:-

|“写入输出”>>WriteToText('TestNewPipeline.txt'))
但是,创建的所有文件都位于一个前缀为“beam temp TestNewPipeline.txt-[somehash]”的目录中,并被分成10组,这不是我所期望的

我尝试过使用窗口功能,但它似乎没有太大的效果,所以要么我完全误解了这个概念,要么我做了一些完全错误的事情

窗口的代码为:-

|“Window”>>beam.WindowInto(beam.Window.FixedWindows(5))
我假设这会导致文本文件的输出被写入一个5秒的静态窗口,但事实并非如此

完整代码如下:-

options=PipelineOptions()
选项。按(标准选项)查看。流=真
def格式_消息(消息,时间戳=beam.DoFn.timestamp参数):
格式化消息={
“数据”:message.data,
“属性”:str(message.attributes),
“时间戳”:浮点(时间戳)
}
返回格式化的消息
梁管道(选项=选项)为p:
(p
|'Read From Pub Sub'>>readfrom pubsub(subscription='projects/[my proj]/subscriptions/[my subscription]',带有_attributes=True)
|'Window'>>beam.WindowInto(beam.Window.FixedWindows(5))
|“映射消息”>>beam.Map(格式化消息)
|“写入输出”>>WriteToText('TestNewPipeline.txt')
)
结果=p.运行()
正如预期的那样,进程无限期运行并成功地从订阅中读取消息;但是,它只将它们写入梁临时文件。有人能帮我指出哪里出了问题吗

更新:

根据Jason的评论,我对管道做了更多的修改:-

class AddKeyToDict(beam.DoFn):
def流程(自身、要素):
返回[(元素['rownumber',元素]
梁管道(选项=选项)为p:
(p
|'Read From Pub Sub'>>ReadFromPubSub(subscription=known_args.input_subscription)#还不能使属性工作!,其中_attributes=True)
#尝试1 |“映射消息”>>beam.Map失败(格式化消息)
#尝试2 |“解析JSON”>>beam.Map(格式化消息元素)失败
|'Parse to Json'>>beam.Map(lambda x:Json.loads(x))
|'addkey'>>beam.ParDo(AddKeyToDict())
|'Window'>>beam.WindowInto(beam.Window.FixedWindows(5),触发器=后处理时间(15),累加模式=累加模式。丢弃)
|'Group'>>beam.GroupByKey()
|“写入输出”>>WriteToText(已知的参数输出文件)
)
我还不能从PubSub中提取消息的id或发布时间,所以我只使用消息中生成的行数。在这一点上,我仍然只创建临时文件,而没有任何内容累积到最终文件中?我开始怀疑Python实现是否仍然有点欠缺,我将不得不学习Java….

来自:

如果使用
窗口
变换设置窗口功能,则每个元素都被指定给一个窗口,但只有在
GroupByKey
Combine
跨窗口和键聚合后,才会考虑窗口

由于本例中似乎没有键的概念,您可以尝试从以下位置使用
Combine

如果使用
窗口
变换设置窗口功能,则每个元素都被指定给一个窗口,但只有在
GroupByKey
Combine
跨窗口和键聚合后,才会考虑窗口


由于在本例中似乎没有键的概念,您是否可以尝试使用
组合

与Apache Beam Python合作,Python中还不支持对GCS(或本地文件系统)的流式写入,因此为什么不发生流式写入;当前仅支持无界目标(例如,大查询表)


显然,这将在即将发布的Beam for Python v2.14.0中得到支持。

与Apache Beam Python合作后,Python还不支持对GCS(或本地文件系统)的流式写入,因此,流式写入不会发生;当前仅支持无界目标(例如,大查询表)


显然,这将在即将发布的Beam for Python v2.14.0中得到支持。

我想知道这是否与此有关。理想情况下,我希望在本例中使用来自PubSub的消息id作为键。我已经修改了Read-From-Pub-Sub转换,以包含id_-label参数,但我不确定如何将其作为一个键来处理,以便执行GroupByKey
|“Read From Pub Sub”>>readfrom pubsub(subscription=known_args.input_subscription,id_label='MESSAGE_id',且_attributes=True)
您需要使用beam.Map将消息转换为以消息id为键的KV。因为GroupByKey在KVs上运行。我不知道如何在Python中实现这一点,但是有足够的文档可以在Java中实现这一点。好的,谢谢你,我将尝试解决这个问题。不幸的是,我不精通Python,但对Java更不精通,因此选择前者来学习这一点!为了澄清,在KV中,消息\u id将是键,而整个消息内容将是值?我已经设法添加了KV对,而不是从消息\u id,因为我根本不知道如何从任何地方提取它。用变化更新主体;似乎仍然无法正常工作。您可以使用将消息id填充到属性映射中,然后在format\u消息函数中读取属性映射。我想知道