Skip to content

[Data] Support reading multiple paths in read_lance - #64560

Open
dragongu wants to merge 2 commits into
ray-project:masterfrom
dragongu:feature/multi_paths_for_read_lance
Open

[Data] Support reading multiple paths in read_lance#64560
dragongu wants to merge 2 commits into
ray-project:masterfrom
dragongu:feature/multi_paths_for_read_lance

Conversation

@dragongu

@dragongu dragongu commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Why are these changes needed?

Our upstream produces data as many small Lance directories, but
ray.data.read_lance only accepts a single uri, so reading them all requires
calling read_lance per directory and unioning the results by hand.

This PR lets read_lance also accept a list of URIs:

ds = ray.data.read_lance(["./part_0.lance", "./part_1.lance", "./part_2.lance"])

Passing a single string works exactly as before.

Note: a read task can only read fragments from one Lance dataset, so the number
of read tasks is at least the number of directories, even when parallelism is
smaller.

Related issue number

None.

Checks

  • I've signed off every commit (by using the -s flag, i.e., git commit -s) in this PR.
  • I've run scripts/format.sh to lint the changes in this PR.
  • Unit tests added in python/ray/data/tests/test_lance.py.

@dragongu
dragongu requested a review from a team as a code owner July 7, 2026 03:18

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for reading from multiple Lance datasets in read_lance by allowing a list of URIs. It updates LanceDatasource to handle multiple datasets, distributing the requested parallelism proportionally across them, and adds corresponding unit tests. Feedback is provided to cap the calculated dataset parallelism at the number of fragments to prevent performance issues and potential OOMs when parallelism is extremely high.

Comment thread python/ray/data/_internal/datasource/lance_datasource.py Outdated
Comment thread python/ray/data/_internal/datasource/lance_datasource.py Outdated
@dragongu
dragongu force-pushed the feature/multi_paths_for_read_lance branch 2 times, most recently from 089bc1a to 2e6b3da Compare July 7, 2026 03:40
@ray-gardener ray-gardener Bot added data Ray Data-related issues community-contribution Contributed by the community labels Jul 7, 2026
Comment thread python/ray/data/_internal/datasource/lance_datasource.py Outdated
@dragongu
dragongu force-pushed the feature/multi_paths_for_read_lance branch from 2e6b3da to 9bb0e6d Compare July 20, 2026 06:55
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

This pull request has been automatically marked as stale because it has not had
any activity for 14 days. It will be closed in another 14 days if no further activity occurs.
Thank you for your contributions.

You can always ask for help on our discussion forum or Ray's public slack channel.

If you'd like to keep this open, just leave any comment, and the stale label will be removed.

@github-actions github-actions Bot added the stale The issue is stale. It will be closed within 7 days unless there are further conversation label Aug 3, 2026
@github-actions github-actions Bot added unstale A PR that has been marked unstale. It will not get marked stale again if this label is on it. and removed stale The issue is stale. It will be closed within 7 days unless there are further conversation labels Aug 7, 2026

@owenowenisme owenowenisme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left minor nits but LGTM now, will approve after conflict solved.
FYI, conflict is from #64881

Comment thread python/ray/data/_internal/datasource/lance_datasource.py Outdated
Comment thread python/ray/data/read_api.py
@dragongu
dragongu force-pushed the feature/multi_paths_for_read_lance branch 2 times, most recently from 8f07e79 to ec437e8 Compare August 8, 2026 16:13
Comment thread python/ray/data/tests/datasource/test_lance.py
Comment thread python/ray/data/_internal/datasource/lance_datasource.py
@richardliaw

Copy link
Copy Markdown
Contributor

tests failing?

@richardliaw richardliaw added the go add ONLY when ready to merge, run all tests label Aug 8, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 14644d5. Configure here.

Comment thread python/ray/data/_internal/datasource/lance_datasource.py
@dragongu
dragongu force-pushed the feature/multi_paths_for_read_lance branch from 14644d5 to 0a67eac Compare August 9, 2026 01:04
Extend `read_lance` to accept a list of URIs so that data from multiple
Lance datasets is combined into a single Dataset. Fragments across all
datasets are flattened and split globally by parallelism, so read tasks
are balanced by fragment count rather than requiring at least one task
per dataset. A single read task can span multiple datasets by creating
one scanner per dataset.

Also:
- Use the dataset-level schema (unified with type promotion across
  datasets) as the ReadTask output schema, which is correct under Lance
  schema evolution.
- Reject `scanner_options['fragments']` when reading multiple datasets,
  since fragments are bound to a specific dataset.
- Reject an empty URI list.

Signed-off-by: dragongu <andrewgu@vip.qq.com>
@dragongu
dragongu force-pushed the feature/multi_paths_for_read_lance branch from 0a67eac to 20905b9 Compare August 9, 2026 01:08
@dragongu

dragongu commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

tests failing?

@richardliaw Fixed now, thanks!

_fill_missing_columns null-filled columns for the unified ReadTask schema
but left each block in its per-dataset scanner order. When a dataset's
column order differed from the unified schema, the block violated the
advertised schema contract and broke positional consumers like
Table.cast and RecordBatchReader.from_batches. Reorder each block via
select(schema.names) after null-fill; projection under `columns=` is
still returned untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Drakery <dragongu@example.com>
Signed-off-by: dragongu <andrewgu@vip.qq.com>
@richardliaw

Copy link
Copy Markdown
Contributor

@owenowenisme did you review?

@owenowenisme owenowenisme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Contributed by the community data Ray Data-related issues go add ONLY when ready to merge, run all tests unstale A PR that has been marked unstale. It will not get marked stale again if this label is on it.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants