Skip to main content
Geneva UDFs can consume and produce Lance Blob columns — large binary objects (roughly 1 MB to 100s of MB per value) such as images, audio clips, or documents. Blob columns keep large payloads out of the regular column data path and provide lazy, file-like access on read. Lance has two blob encodings, and Geneva supports both: For Blob v2 output columns on data storage version 2.2+, Geneva checkpoints compact descriptors instead of the payload bytes and writes payloads through PyLance’s bulk blob writer, which significantly reduces checkpoint I/O for large backfills. This requires pylance>=9.0.0b24.

Writing blob columns from UDFs

Blob v1

For a scalar UDF, return bytes, set data_type to pa.large_binary(), and add the field_metadata that marks the column as blob-encoded:
A batched (pa.RecordBatch) UDF is similar — return a pa.large_binary() array:
The destination table must use data storage version 2.0 or newer:

Blob v2

The simplest form is a scalar UDF whose data_type is BlobType() — return the payload as bytes (or None):
For production pipelines, declare the output as a struct with a lance.blob_field(...) child. This is the pattern Geneva’s large-scale image pipelines use — the struct carries the payload plus any per-row metadata (an error string, dimensions, a content hash, and so on):
Scalar UDFs return the blob child as inline bytes (or None); URI-style descriptors like {"uri": ...} are not accepted. A batched UDF builds the struct explicitly, using lance.blob_array(...) for the blob child:
The destination table must use data storage version 2.2 or newer:

Reading blob columns in UDFs

Blob v1

Blob v1 columns arrive in scalar UDFs as lazy BlobFile objects — call .read() to fetch the payload:

Blob v2

Blob v2 payloads arrive as bytes. Reference a nested blob with its dotted path via the (udf, input_columns) tuple form:

Reading blobs back

Table.take_blobs returns lazy BlobFile handles for both encodings. Use the dotted path for a blob nested in a struct:
For bulk reads of Blob v2 payloads keyed by physical row address, drop down to the Lance dataset:

API Reference

  • UDF@udf decorator for defining blob-producing and blob-consuming functions
  • Tableadd_columns(), backfill(), take_blobs()
  • Lance blob guide — the underlying Blob v1/v2 storage model