Skip to content

[Data] ray.data.read_delta silently drops columns on Delta tables with column mapping enabled #64854

Description

@daturkel

What happened + What you expected to happen

ray.data.read_delta silently produces an incorrect schema when reading a Delta table that has Delta Column Mapping enabled. Columns added after column mapping was enabled are stored in the physical parquet files using UUID-based physical names (e.g. col-4d014c4b-7d15-4d7b-a89e-blah-blah). The Delta log contains the mapping from these UUIDs to logical column names, but ray.data.read_delta does not apply this translation. As a result, the returned dataset's schema contains UUID column names for those columns rather than their logical names, and any attempt to select or cast those columns by their logical name raises a KeyError.

Root Cause Chain

  1. ray.data.read_delta calls DeltaTable(path, version=version).file_uris() from deltalake to get parquet paths, then passes them to ray.data.read_parquet.
  2. ray.data.read_parquet infers the dataset schema from pq_ds.fragments[0].physical_schema — the first parquet file's raw schema.
  3. For a column-mapping-enabled Delta table, the physical parquet file stores columns using UUID names. The logical name translation lives in the Delta log metadata, which deltalake 1.6.1 does not apply to the physical schema exposed to Ray.
  4. The resulting dataset schema contains col-4d014c4b-7d15-4d7b-a89e-<redacted> double where <string column_name> double is expected.

Observed Schema (excerpt)

is_2_way                                       bool       ← last logical name
col-4d014c4b-7d15-4d7b-a89e-40dfdca76a22      double     ← should be a logical name
col-8c0bb653-f5db-4b02-a361-d29086e7f2ed      double
...
_row-id-col-9e9b0ae3-...                       int64
_row-commit-version-col-7bc4f86e-...           int64
  • DESCRIBE TABLE confirms real column name exists at ordinal position 356 with type double
  • SHOW TBLPROPERTIES confirms delta.columnMapping.mode is enabled on the table
  • DESCRIBE HISTORY shows no ADD COLUMN operations — the column has existed since table creation; only its physical representation changed when column mapping was enabled
  • Downgrading deltalake to 0.x (which applied column mapping translation correctly) resolves the issue

Expected Behavior

ray.data.read_delta should apply the Delta log's column mapping metadata to translate physical UUID column names to their logical names before constructing the dataset schema, consistent with how deltalake 0.x and Databricks' native readers behave.

Further diagnostics

Per Anyscale's suggestion, we supplied a schema on read:

dt = DeltaTable("s3://my-bucket/my-table",
                storage_options={"AWS_REGION": "...})

col_map = {
    field.metadata.get("delta.columnMapping.physicalName", field.name): field.name
    for field in dt.schema().fields
}

ds = ray.data.read_unity_catalog(...)
ds = ds.rename_columns(col_map)

This fixes reads (though ideally would not be required), but is incompatible with adding row_filters to read_unity_catalog calls because row filters using logical table names are not mapped to the physical column name. The filter is then silently ignored, causing a full table scan.

Per Anyscale, it seems like we should've hit this error from deltalake, but did not.

Versions / Dependencies

  • Ray: 2.55.1
  • deltalake: 1.6.1
  • PyArrow: 21.0.0
  • Python: 3.11

Reproduction script

Nontrivial to reproduce in isolation as this requires a databricks table with column mapping.

Issue Severity

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething that is supposed to be working; but isn'tcommunity-backlogdataRay Data-related issuesneeds-repro-scriptIssue needs a runnable script to be reproducedstabilitytriageNeeds triage (eg: priority, bug/not-bug, and owning component)

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions