Trouble saving repeated protobuf object to file Python
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Protocol Buffers (protobuf) does not natively support writing multiple messages to a single file — there is no built-in delimiter between messages in the binary format. When you serialize multiple protobuf objects to a file, they are concatenated as raw bytes, and reading them back requires knowing where each message ends and the next begins. The standard solution is to prefix each message with its length (length-delimited format). The google.protobuf Python library does not provide this out of the box, so you must implement it manually.
The Problem
The binary data of multiple messages is concatenated without separators. ParseFromString cannot determine where one message ends and the next begins.
Solution 1: Length-Delimited Format (Recommended)
Prefix each message with its byte length using varint encoding:
Solution 2: Fixed-Size Length Prefix
Simpler but less space-efficient for small messages:
Solution 3: Wrapper Message with Repeated Field
Instead of writing multiple messages, wrap them in a container message:
This is the simplest approach but requires all data to fit in memory at once.
Working with Repeated Fields
Solution 4: JSON Lines (One JSON per Line)
For human-readable storage:
Common Pitfalls
- Writing multiple messages without length delimiters: Raw
SerializeToString()output has no message boundary markers. Concatenating multiple messages and then reading produces corrupt data. Always use length-delimited format or a wrapper message. - Using
MergeFromStringinstead ofParseFromString:MergeFromStringappends to existing data in the message instead of replacing it. If you reuse a message object in a read loop without clearing it, fields accumulate. UseParseFromString(which clears first) or callmessage.Clear()beforeMergeFromString. - Assigning to repeated fields directly:
person.hobbies = ["a", "b"]raisesAttributeErrorin protobuf. Repeated fields are special containers that must be modified with.append(),.extend(), or slice assignment. Usedel person.hobbies[:]to clear and.extend()to set new values. - Forgetting to compile
.protofiles: The Python classes (person_pb2.py) are generated byprotoc --python_out=. person.proto. If you modify the.protofile, you must regenerate the Python module. Importing a stale_pb2.pyfile causes field mismatches. - Large files with the wrapper approach: Putting all messages in a
PeopleListcontainer requires loading everything into memory at once. For millions of records, use length-delimited streaming instead.
Summary
- Protobuf has no built-in multi-message file format — you must delimit messages yourself
- Use varint length prefix (
_EncodeVarint/_DecodeVarint) for standard length-delimited format - Alternatively, use
struct.pack('>I', length)for fixed 4-byte length prefixes - Wrap multiple messages in a container message (
repeatedfield) for simple cases - Use
.append()and.extend()for repeated fields — direct assignment does not work - Regenerate
_pb2.pyfiles withprotocafter modifying.protodefinitions
Related reading
- True Positive Rate and False Positive Rate TPR, FPR for Multi-Class Data in python
- Truth value of a Series is ambiguous. Use a.empty, a.bool, a.item, a.any or a.all
- Trying to mock datetime.date.today, but not working
- Trying to use LinearRegressor
- Trouble understanding YAML file
- Trouble when changing Spring Boot version from 2.0.3.RELEASE to 2.1.0.BUILD-SNAPSHOT
- Trying to write my own Neural Network in Python
- ''tuple'' object has no attribute ''layer''
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.