mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-14 15:52:26 +00:00
Since lancedb#4180, create_materialized_view runs the initial refresh before it returns (with_no_data=True skips it), so the page's first manual refresh now writes 0 rows, not 1. The example now reads the populated view and refreshes after a source change, and its snippets come from docs/web-tests/py/test_materialized_view.py. A note scopes the behavior: 0.39 and earlier create the view empty. Pages that said a refresh computes the rows now say it brings them up to date, and the SQL note no longer says an incremental refresh covers only added rows.
101 lines
3.6 KiB
Plaintext
101 lines
3.6 KiB
Plaintext
---
|
|
title: "Materialized view"
|
|
sidebarTitle: "Materialized View"
|
|
description: "Create, open, list and drop a table whose contents are defined by a query."
|
|
icon: table
|
|
keywords: ["materialized view", "create_materialized_view", "catalog", "ddl"]
|
|
---
|
|
|
|
A materialized view is a table whose contents are defined by a query over
|
|
another table. The query is recorded in the view's schema, and a refresh
|
|
brings its stored rows up to date with the source.
|
|
|
|
The result is an ordinary table -- queryable, indexable, searchable, and present
|
|
in `table_names()`. Nothing about reading it is special.
|
|
|
|
This page covers creating and managing one. Keeping it current is
|
|
[Refresh a materialized view](/feature-engineering/materialized-views).
|
|
|
|
<Note>
|
|
In SQL, see [`REFRESH MATERIALIZED VIEW`](/sql/dml/refresh#refresh-materialized-view) and [`SHOW MATERIALIZED VIEWS`](/sql/ddl/materialized-view#show).
|
|
</Note>
|
|
|
|
## Creating one {#create}
|
|
|
|
<CodeGroup>
|
|
```python Python icon="python"
|
|
view = db.create_materialized_view(
|
|
"recent_docs",
|
|
source="documents",
|
|
select=["id", "title", "embedding"],
|
|
where="created_at > '2026-01-01'",
|
|
)
|
|
```
|
|
|
|
```typescript TypeScript icon="square-js"
|
|
const view = await db.createMaterializedView("recent_docs", {
|
|
source: "documents",
|
|
select: ["id", "title", "embedding"],
|
|
where: "created_at > '2026-01-01'",
|
|
});
|
|
```
|
|
</CodeGroup>
|
|
|
|
`source` names the table it derives from. `select`, `where` and `limit` record
|
|
the query -- there is no separate definition step.
|
|
|
|
<Warning>
|
|
The source table must have **stable row ids**, and they cannot be enabled after
|
|
a table exists. A table created without them cannot become a view's source
|
|
without being recreated.
|
|
|
|
Set `new_table_enable_stable_row_ids` in
|
|
[storage options](/management/database#storage-options) when you create the
|
|
source, not when you create the view.
|
|
</Warning>
|
|
|
|
## Opening, listing and dropping {#manage}
|
|
|
|
| | Python | TypeScript | SQL |
|
|
| --- | --- | --- | --- |
|
|
| create | `create_materialized_view` | `createMaterializedView` | -- |
|
|
| open | `open_materialized_view` | `openMaterializedView` | -- |
|
|
| list | `list_materialized_views` | `listMaterializedViews` | `SHOW MATERIALIZED VIEWS` |
|
|
| refresh | `refresh` | `refresh` | `REFRESH MATERIALIZED VIEW` |
|
|
| drop | `drop_table` | `dropTable` | `DROP TABLE` |
|
|
|
|
<Note>
|
|
`list_materialized_views` finds views by reading every table's schema, so it
|
|
costs one open per table. `SHOW MATERIALIZED VIEWS` asks the server instead and
|
|
is cheaper on a catalog with many tables.
|
|
</Note>
|
|
|
|
A view is dropped with `drop_table`, because a materialized view **is** a table.
|
|
That also means dropping one removes stored rows -- unlike dropping a
|
|
[view](/management/view), which removes only a saved query.
|
|
|
|
## Working with the view {#working}
|
|
|
|
`view.table` is the underlying table, for querying, indexing, or search.
|
|
`view.definition` is the recorded query -- select list, predicate, limit
|
|
-- which is how you check what a view contains without inferring it from the
|
|
rows. Both are properties; on an async view, the definition is read with
|
|
`await view.definition()`.
|
|
|
|
## Against a deployment {#deployment}
|
|
|
|
<Badge color="red">Enterprise</Badge> `create_materialized_view` works on a
|
|
`db://` connection as well as a local one. What changes is that a refresh runs
|
|
across the cluster rather than in your process, and SQL can drive it.
|
|
|
|
## What to read next {#next}
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Refresh a materialized view" icon="arrows-rotate" href="/feature-engineering/materialized-views">
|
|
Incremental refreshes, and what they cost.
|
|
</Card>
|
|
<Card title="Views" icon="eye" href="/management/view">
|
|
The non-materialized counterpart, defined in SQL.
|
|
</Card>
|
|
</CardGroup>
|