mirror of
https://github.com/lancedb/lancedb.git
synced 2026-11-13 14:16:54 +00:00
View APIs now read the native `name`, `query`, and `schema` columns
returned by `CREATE VIEW` and `DESCRIBE VIEW`. The schema JSON carries
the defining database and namespace; the requested namespace identifies
where the view lives. The unreleased JSON-envelope response is removed
without a compatibility fallback.
```python
view = db.create_view("adults", "SELECT name FROM people WHERE age >= 18")
view = db.describe_view("adults")
```
```sql
CREATE VIEW "adults" AS SELECT name FROM people WHERE age >= 18;
DESCRIBE VIEW "adults";
```
Both Python calls execute SQL through the query-backed job adapter and
wait on the resulting query. A job handle uses that query's `id` and
type `query`; reading metadata consumes its completed result rather than
resubmitting the DDL. Creation returns the definition from the creating
execution, with no extra describe request.
119 lines
4.0 KiB
Plaintext
119 lines
4.0 KiB
Plaintext
---
|
|
title: "View"
|
|
sidebarTitle: "View"
|
|
description: "Create, describe, list, and drop saved queries with SQL."
|
|
icon: eye
|
|
keywords: ["create view", "drop view", "sql", "catalog"]
|
|
availability:
|
|
embedded: unavailable
|
|
enterprise: available
|
|
---
|
|
|
|
A view stores a **query**, not rows. Reading it runs the query against current
|
|
data, so a view is never stale, and never faster than the query it wraps. It
|
|
is the counterpart to a [materialized view](/sql/ddl/materialized-view), which
|
|
stores rows and is brought up to date by a refresh; both are
|
|
[catalog objects](/basics/catalog) defined by a query, differing only in when
|
|
that query runs.
|
|
|
|
The SDK methods `create_view`, `describe_view`, `list_views`, and `drop_view`
|
|
submit SQL through the connection's Flight endpoint. `drop_view_async` returns
|
|
a job of type `query` whose single `id` is the SQL query UUID. Waiting confirms
|
|
catalog removal; physical cleanup can continue afterward.
|
|
|
|
## CREATE VIEW {#create}
|
|
|
|
```sql
|
|
CREATE VIEW "recent_matches" AS
|
|
SELECT t1.floats
|
|
FROM "documents" AS t1
|
|
INNER JOIN "categories" AS t2 ON t1.ints = t2.ints
|
|
```
|
|
|
|
The statement returns one row with UTF-8 `name`, `query`, and `schema` columns.
|
|
`query` contains the stored query, including any declared column aliases, and
|
|
`schema` contains its Arrow schema as JSON. The schema metadata keys
|
|
`lancedb::view::default_db` and `lancedb::view::default_namespace` identify the
|
|
defining database and namespace. The root namespace is `public`; nested
|
|
namespace components are separated by `$`.
|
|
|
|
`DESCRIBE VIEW "recent_matches"` returns the same metadata shape. Anything the
|
|
[dialect](/sql/functions) supports can define one: joins, predicates,
|
|
aggregates, window functions.
|
|
|
|
## Reading one {#reading}
|
|
|
|
A view is queried like a table:
|
|
|
|
```sql
|
|
SELECT * FROM "recent_matches" WHERE floats > 0.5
|
|
```
|
|
|
|
Predicates applied to the view compose with the query inside it rather than
|
|
filtering its output afterwards, so a selective filter does not pay for rows
|
|
the view would have produced and then discarded.
|
|
|
|
## DROP VIEW {#drop}
|
|
|
|
```sql
|
|
DROP VIEW "recent_matches"
|
|
```
|
|
|
|
Removes the saved query. Unlike dropping a table, no data is removed: there
|
|
was none to begin with.
|
|
|
|
## Listing {#listing}
|
|
|
|
```sql
|
|
SHOW VIEWS
|
|
SHOW VIEWS IN "analytics" WHERE name > 'previous_view' LIMIT 100
|
|
```
|
|
|
|
`SHOW VIEWS` returns ascending `name` values. The `name` cursor is scoped to
|
|
the selected namespace.
|
|
|
|
Object commands retain their small results in shared storage even when general
|
|
query-result copying is disabled, so asynchronous polling can use any query node.
|
|
|
|
Views and tables share a namespace, and both are things you can query. The
|
|
catalog distinguishes them:
|
|
|
|
| | |
|
|
| --- | --- |
|
|
| view names | the views in the database |
|
|
| table names | the tables |
|
|
| relation names | everything queryable (both) |
|
|
|
|
Use the relation listing when the question is "what can I select from," and the
|
|
separate listings when the distinction matters: before dropping, for
|
|
instance, since dropping a view removes only the saved query while dropping a
|
|
table removes data.
|
|
|
|
## Choosing between a view and a materialized view {#choosing}
|
|
|
|
| | View | Materialized view |
|
|
| --- | --- | --- |
|
|
| Stores | the query | the rows |
|
|
| Freshness | always current | as of the last refresh |
|
|
| Read cost | the full query, every read | a table scan |
|
|
| Write cost | none | a refresh |
|
|
|
|
Reach for a **view** when the query is cheap, or when reading stale rows would
|
|
be wrong. Reach for a **materialized view** when the query is expensive and the
|
|
data changes less often than it is read.
|
|
|
|
The privileges are separate too: `CREATE_VIEW` and `CREATE_MATERIALIZED_VIEW`
|
|
are distinct grants on a namespace, so the ability to create one does not imply
|
|
the other. See [Authorization](/governance/authorization).
|
|
|
|
## What to read next {#next}
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Materialized View" icon="table" href="/sql/ddl/materialized-view">
|
|
The stored-rows counterpart.
|
|
</Card>
|
|
<Card title="Management" icon="folder-tree" href="/management">
|
|
Where views fit among the other catalog objects.
|
|
</Card>
|
|
</CardGroup>
|