Files
lancedb/docs/web/curation/inspect-datasets.mdx
T
Jack YeandClaude Sonnet 5 de95ed3f6d docs: overhaul curation, feature engineering, security and deployment guides (#4748)
A broad documentation pass across the areas LanceDB Enterprise and
Embedded
diverge on most:

**Data Curation** -- GPU Function execution, Slurm scheduling (and what
Slurm is, for readers new to it), blob late materialization as its own
page, joins, aggregation/profiling, sampling, near-duplicate detection,
chunking, distributed shuffle, and IVF-partition clustering.

**Feature Engineering** -- computed columns and materialized views,
restructured to lead with the Function-based path and show the SQL form
side by side with Python throughout; a single Auto Refresh page instead
of
duplicating scheduling details on every refresh page; adaptive
execution;
checkpointing; GPU and Slurm placement for refresh workers; a Training
Cache page for the PyTorch data loader's automatic cache benefit.

**Security & Governance** -- an Audit Log reference (schema, access,
grants), Secrets promoted to an ordinary catalog object with their own
SQL
DDL and a vending/rotation guide, and privilege-table fixes verified
against the authorization source.

**Deployment & Maintenance** -- Horizontal Scaling and OpenTelemetry
moved
into a real Deployment area; Automated Cleanup folded into Intelligent
Auto-Maintenance (every other maintenance decision already lived there);
RTE Compaction and Advanced Conflict Resolution documented in depth.

**Landing page** -- the Enterprise feature comparison table reorganized
(several redundant or stale rows removed, several new areas added), and
the
"why Enterprise" bullets replaced with ones tied to a concrete page
(Performance, Scale, Fault tolerance, Multicloud deployment, Simplify
operations) instead of vague promises.

Plus a full pass addressing lancedb-gatekeeper's review: a real
test-safety
bug (a quickstart test could silently overwrite and delete a
deployment's
own `frames` table), a fabricated SQL statement with no backing
implementation, an actual dedup-guarantee bug in `take_row_ids`, and
dozens
of documentation-accuracy fixes verified against source rather than
taken
on faith -- each either fixed, or left with an explicit note on why it
needs a feature or deployment owner's sign-off instead of being guessed
at.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_018PXMCbRH6i5w47TsjeEUMT

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-03 16:17:24 -08:00

242 lines
8.5 KiB
Plaintext

---
title: "Inspect Datasets"
sidebarTitle: "Inspect Datasets"
description: "Query a table, a HuggingFace dataset, or a dataset in object storage the same way, with plain SELECT, WHERE, projection and LIMIT."
icon: database
keywords: ["select", "where", "filter", "projection", "limit", "huggingface", "storage integration", "sql", "inspect"]
availability:
embedded: unavailable
enterprise: available
---
The same `SELECT` statement inspects three kinds of source: a table
already in your database, a HuggingFace dataset, or a dataset in object
storage -- once a [storage integration](/management/storage-integration)
covers the latter two. Nothing is downloaded or imported until you choose
to import it.
## The basics: project, filter, limit {#basics}
A table name, a HuggingFace URI, and an object-storage URI all work the
same way after `FROM`:
<CodeGroup>
```sql SQL icon="database"
SELECT id, text
FROM documents
WHERE text IS NOT NULL
LIMIT 100
```
</CodeGroup>
- **Project** -- name the columns you need (`id, text`) instead of
`SELECT *`, especially for a source with large or many columns.
- **Filter** -- `WHERE` narrows rows before they come back; combine
predicates with `AND`/`OR` the same as any other table.
- **Limit** -- `LIMIT n` caps how many rows return. It bounds the result,
not the read: a remote source is still fetched at file or row-group
granularity, so a small `LIMIT` on a source with large files or row
groups can still touch more data than the row count suggests.
The rest of this page swaps `documents` for a HuggingFace or
object-storage source -- the `SELECT`/`WHERE`/`LIMIT` syntax above doesn't
change.
## Inspect a HuggingFace dataset {#huggingface}
A single-quoted HuggingFace dataset URI works directly in a SQL `FROM`
clause, the same as a table name -- no separate download, no intermediate
file on disk:
<CodeGroup>
```sql SQL icon="database"
SELECT id, text
FROM 'hf://datasets/owner/repo/data/train-*.parquet'
WHERE text IS NOT NULL
LIMIT 100
```
</CodeGroup>
<CodeGroup>
```python Python icon="python"
reader = db.execute_query("""
SELECT id, text
FROM 'hf://datasets/owner/repo/data/train-*.parquet'
WHERE text IS NOT NULL
LIMIT 100
""")
sample = reader.read_all().to_pylist()
```
</CodeGroup>
The URI is `hf://datasets/<owner>/<repo>[@<revision>]/<path>`. `<path>` can
be one Parquet file, a directory, or a glob: `*` matches within one
directory, `**` matches across directories, and a repository root selects
every Parquet file beneath it. Select a dataset configuration or split by
including it in the path. The default revision is `main`; each statement
resolves the revision to a commit once, so every worker reads the same
snapshot. This source reads Parquet files -- it does not run a dataset's
own generation scripts, and it does not compute embeddings or build
indexes, so [chunk](/curation/chunking), embed, or index the result as a
separate step, the same as data from any other source.
<Note>
Files matched by one statement must have compatible schemas, and an
unmatched path is an error rather than a silent fallback to a different
split. Nested Parquet values come through as-is; a floating-point list is
not automatically converted into a fixed-size vector column.
</Note>
## Inspect a dataset in object storage {#object-storage}
An `s3://`, `gs://` or `az://` prefix covered by a storage integration
reads an existing **Lance** dataset at that prefix, the same way as a
managed table:
<CodeGroup>
```sql SQL icon="database"
SELECT id, text
FROM 's3://customer-data/raw/documents.lance'
WHERE text IS NOT NULL
LIMIT 100
```
</CodeGroup>
This reads a dataset another process already wrote in Lance format, not
an arbitrary file format -- there is no Parquet-style reader for cloud
storage the way there is for `hf://`. See
[Storage Integration](/sql/ddl/storage-integration#read-import) for every
provider's setup.
## Access a private repository or bucket {#access}
A private HuggingFace repository, one subject to HuggingFace's
authenticated rate limits, or any non-public bucket needs a
[storage integration](/management/storage-integration) covering it. For
HuggingFace that integration is bound to a token
[Secret](/management/secret); for a non-public S3 bucket it can instead be
an IAM role integration, which needs no Secret at all -- see
[AWS S3](/ingestion/define-storage-integration#aws).
<CodeGroup>
```python Python icon="python"
db.create_secret("hf_token", "<your-hugging-face-token>")
# create_storage_integration is not in a released SDK yet; use the SQL
# form below until it ships.
db.execute_query("""
CREATE STORAGE INTEGRATION private_hub
STORAGE_PROVIDER = 'HUGGINGFACE'
STORAGE_PREFIX = 'hf://datasets/owner/private/data/'
HUGGINGFACE_TOKEN_SECRET = hf_token
""").read_all()
reader = db.execute_query(
"SELECT * FROM 'hf://datasets/owner/private/data/*.parquet' LIMIT 10"
)
```
```sql SQL icon="database"
CREATE SECRET hf_token TYPE = GENERIC_STRING SECRET_STRING = '<your-hugging-face-token>'
CREATE STORAGE INTEGRATION private_hub
STORAGE_PROVIDER = 'HUGGINGFACE'
STORAGE_PREFIX = 'hf://datasets/owner/private/data/'
HUGGINGFACE_TOKEN_SECRET = hf_token
SELECT * FROM 'hf://datasets/owner/private/data/*.parquet' LIMIT 10
```
</CodeGroup>
{/*
Draft for the storage-integration SDK release (#4618, #4775). Keep this
section unpublished until create_storage_integration ships in a release; it
is not in v0.41.0.
<CodeGroup>
```python Python icon="python"
db.create_secret("hf_token", "<your-hugging-face-token>")
db.create_storage_integration(
"private_hub", "hf://datasets/owner/private/data/",
storage_provider="HUGGINGFACE",
huggingface_token_secret="hf_token",
)
reader = db.execute_query(
"SELECT * FROM 'hf://datasets/owner/private/data/*.parquet' LIMIT 10"
)
```
</CodeGroup>
*/}
A query never names the integration: the planner matches the most specific
`STORAGE_PREFIX` that covers the URI being read, across every integration
the caller has `USAGE` on. A HuggingFace integration always needs
`HUGGINGFACE_TOKEN_SECRET`; creating one without it is rejected. For public
access, register no integration for that prefix at all -- an `hf://` read
that matches no integration is anonymous, with no environment-variable
fallback. See
[Storage Integration](/management/storage-integration) for every provider
and the full credential model.
## Import into a table {#import}
Once you've inspected a source and it looks right, `CREATE TABLE ... AS
SELECT` imports it:
<CodeGroup>
```sql SQL icon="database"
CREATE TABLE imported AS
SELECT *
FROM 'hf://datasets/owner/repo/data/train-*.parquet'
```
</CodeGroup>
<CodeGroup>
```python Python icon="python"
db.execute_query("""
CREATE TABLE imported AS
SELECT * FROM 'hf://datasets/owner/repo/data/train-*.parquet'
""").read_all()
table = db.open_table("imported")
```
</CodeGroup>
This `CREATE TABLE AS SELECT` runs as a distributed import when the
deployment has an available plan-executor fleet: the planner assigns
disjoint file and row-group ranges to workers, each worker writes
uncommitted Lance files directly to the destination, and a coordinator
commits the completed table from their transaction metadata once every
worker finishes. A query with a global limit, aggregation or join keeps
its usual coordination; a small import can run as one local task without a
fleet. The table becomes queryable only after that final commit --
nothing partial is ever visible, and a failed or cancelled import can
resume the same durable job from its retained attempt rather than
restarting from nothing. To start over after a failed one-off import
instead, drop the partial table and rerun the statement.
<Note>
Importing requires a native database with `database_manifest_enabled`.
Combining a HuggingFace source with a WAL-backed destination table in one
CTAS is rejected, since the import cannot publish a base-only read that
omits the destination's unflushed data.
</Note>
## What to read next {#next}
<CardGroup cols={2}>
<Card title="Storage Integration" icon="cloud" href="/management/storage-integration">
The credential object behind private repository access.
</Card>
<Card title="Create a Function" icon="code" href="/curation/create-function">
Add embeddings or derived columns to the imported data.
</Card>
<Card title="Chunk records into multiple rows" icon="diagram-subtask" href="/curation/chunking">
Split long text or media fields after importing.
</Card>
<Card title="Table" icon="table" href="/sql/ddl/table#create">
`CREATE TABLE AS SELECT` syntax and options in full.
</Card>
</CardGroup>