Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write just one file per window with Apache Beam Python `WriteToFiles` transform

need some help. I have some trivial task reading from Pub/Sub and write to batch file in GCS, but have some struggle with fileio.WriteToFiles

with beam.Pipeline(options=pipeline_options) as p:
  input = (p | 'ReadData' >> beam.io.ReadFromPubSub(topic=known_args.input_topic).with_output_types(bytes)
             | "Decode" >> beam.Map(lambda x: x.decode('utf-8'))
             | 'Parse' >> beam.Map(parse_json)
             | ' data w' >> beam.WindowInto(
                 FixedWindows(60),
                 accumulation_mode=AccumulationMode.DISCARDING
             ))

  event_data = (input
             | 'filter events' >> beam.Filter(lambda x: x['t'] == 'event')
             | 'encode et' >> beam.Map(lambda x: json.dumps(x))
             | 'write events to file' >> fileio.WriteToFiles(
                    path='gs://extention/ga_analytics/events/', shards=0))

I need one file after my window fires, but the number of files is equal to the number of messages from Pubsub, can anyone help me? current output files but i need only one file.

like image 717
Andrey Panchenko Avatar asked Sep 26 '26 14:09

Andrey Panchenko


1 Answers

I recently ran into this issue and dug into the source code:

fileio.WriteToFiles will attempt to output each element in the bundle as an individual file. WireToFiles will only fallback to writing to sharded files if the number of elements exceeds the number of writers.

To force a single file to be created for all elements in the window, set max_writers_per_bundle to 0

WriteToFiles(shards=1, max_writers_per_bundle=0)
like image 163
JMM Avatar answered Sep 28 '26 05:09

JMM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!