code: def pack_lob_data(remaining_size, payload, row_header_start_pos, row_lobs):
          
          unwritten_lobs = collections.deque()
          for lob_buffer in row_lobs:
              # Calculate relative position of lob within the binary packed parameter row.
              # Add +1, Hana counts from 1, not 0!
              rel_lob_pos = payload.tell() - row_header_start_pos + 1
  
              # Calculate how much space is left in message for lob data:
              max_data_to_write = min(lob_buffer.encoded_lob_size, remaining_size - payload.tell())
              payload.write(lob_buffer.encoded_data.read(max_data_to_write))
              is_last_data = max_data_to_write == lob_buffer.encoded_lob_size
              if not is_last_data:
                  # lob has not been written (partially or entirely) into message -> register for further write requests
                  unwritten_lobs.append(lob_buffer)
  
              # Write position and size of lob data into lob header block:
              payload.seek(lob_buffer.lob_header_pos)
              payload.write(lob_buffer.DataType.prepare(None, length=max_data_to_write,
                                                        position=rel_lob_pos, is_last_data=is_last_data))
              # Set pointer back to end for further writing
              payload.seek(0, io.SEEK_END)
          return unwritten_lobs
docs: After parameter row has been written, append the lobs and update the corresponding lob headers
          with lob position and lob size:
          :param payload: payload object (io.BytesIO instance)
          :param row_header_start_pos: absolute position of start position of row within payload
          :param row_lobs: list of row buffer instance (containing binary encoded lob data, header position and DataType)