refresh(), and updates them incrementally as the source changes.
Use a materialized view when you want a persisted, queryable projection of a
source table, for example a filtered subset, a set of derived columns, or a
capped sample. Once refreshed, the view is a normal table, so you can search,
index, and scan it like any other.
Materialized views are available in the LanceDB Python and TypeScript clients
on local databases. Remote (
db://) connections raise the core’s not-supported
error up front (Python: NotImplementedError).This page covers the OSS materialized-view API on a plain LanceDB connection.
If you are looking for Geneva’s UDF-driven materialized views used to backfill
expensive columns, see Materialized views with UDFs.
Prerequisites
The source table must have stable row IDs. LanceDB uses them to track which source rows a view has already materialized, so incremental refresh can survive source compactions. Enable stable row IDs when the source table is created. Stable row IDs cannot be enabled on a table that already exists.Create a view
Callcreate_materialized_view (Python) or createMaterializedView (TypeScript)
on the connection.
selectaccepts column names,(alias, SQL expression)pairs, or a dict / record of the same. A bare column name is quoted as an identifier, so column names with spaces or reserved words work. Omitselectto project every source column.whereis a SQL predicate. Only matching source rows appear in the view.limitcaps the view at that many rows.
Refresh the view
refresh() computes the view from its source. LanceDB picks between two modes:
- Incremental: apply only the source rows added, changed, or removed since the last refresh. Chosen when the source’s changes can be reconciled into the view.
- Rebuild: recompute the view from scratch. Chosen on the first refresh or when the source has changed in ways incremental refresh cannot reconcile (for example, an update on legacy-storage data).
refresh() returns a RefreshMaterializedViewResult with:
Force a full rebuild by passing
full=True (Python) or { full: true }
(TypeScript). Refresh against a specific source version with source_version=
or { sourceVersion: N }.
Query a view
The view’s underlying table is available asview.table in Python (a
LanceTable) and view.table() in TypeScript (a Table). Query, index, and
search it like any other table.
refresh().
Open an existing view
open_materialized_view / openMaterializedView returns a handle whose
definition is read back from the stored schema. Opening a table that is not a
materialized view raises an error.
list_materialized_views / listMaterializedViews returns the names of every
materialized view in the database. It reads every table’s schema, so it costs
one open per table.
Async Python API
The same operations are available on Python’sAsyncConnection, and return
AsyncMaterializedView. definition() and refresh() are coroutines. The
TypeScript API is already async and matches the examples above.
Python