diff --git a/docs/web/basics/catalog.mdx b/docs/web/basics/catalog.mdx
index 133599f16..497f51ebc 100644
--- a/docs/web/basics/catalog.mdx
+++ b/docs/web/basics/catalog.mdx
@@ -27,6 +27,10 @@ resolves the same names to the same tables.
| [View](/management/view) | A saved query. Computed when read, not stored. |
| [Function](/management/function) | Registered code, applied to produce column values. |
+Views and functions exist only on an Enterprise deployment that enables them.
+Materialized views also exist in the embedded library, and a deployment has to
+enable them too.
+
```
database
└── namespace
@@ -63,7 +67,8 @@ and it inherits down the path: reaching a table requires `USAGE` on the
namespace containing it and on the database containing that.
That is the practical reason to put a boundary in the hierarchy -- a namespace
-per team gives you something to grant on. See
+per team gives you something to grant on. A deployment checks these grants only
+when its administrator has configured it to. See
[Authorization](/governance/authorization).
Embedded LanceDB has no such layer. Access is whatever the object store enforces
diff --git a/docs/web/basics/jobs.mdx b/docs/web/basics/jobs.mdx
index 652935ea2..21ad7ed2f 100644
--- a/docs/web/basics/jobs.mdx
+++ b/docs/web/basics/jobs.mdx
@@ -4,6 +4,13 @@ sidebarTitle: "Job"
description: "Work that outlives the call that started it: submitting, waiting, inspecting, cancelling."
icon: hourglass-half
keywords: ["job", "async", "background", "events", "cancel", "refresh"]
+availability:
+ oss: available
+ enterprise: available
+ summary: >-
+ Long-running operations return a job handle in the embedded library and on
+ a deployment. Listing jobs, reopening them by id and reading their events
+ need a deployment, where the work runs on the server.
---
Some operations take longer than a request should. Building an index over a
@@ -35,7 +42,9 @@ a **job** immediately.
The blocking form is not a different operation -- it submits the same job and
waits. Reach for the `_async` form when you want to do something else meanwhile,
-run several at once, or survive the client going away.
+run several at once, or survive the client going away. On a deployment,
+`create_index` returns once the build is submitted unless you pass
+`wait_timeout`, and `refresh_column` has no blocking form.
## Submitting and waiting {#waiting}
@@ -155,8 +164,9 @@ in-process.
## Finding and cancelling jobs {#managing}
-The connection lists and reopens jobs, so a handle lost to a restarted process
-is recoverable from its id.
+On a deployment, the connection lists and reopens jobs, so a handle lost to a
+restarted process is recoverable from its id. A local database keeps no jobs to
+list, and these calls raise there.
```python Python icon="python"
@@ -189,8 +199,10 @@ parsing it or storing it to resume the job later is not supported.
A local database has no server to run anything, so its operations run in your
process. They still return a handle, so the same code works against both -- but
-one with nothing behind it: `id` is `None`, `status()` reports `"finished"`,
-`wait()` returns immediately, `cancel()` does nothing, and `events()` raises.
+one with no server behind it: `id` is `None` and `events()` raises. An operation
+still running in your process reports `"running"`, `wait()` waits for it and
+`cancel()` stops it; one that finished before the call returned, such as a local
+`drop_table_async`, reports `"finished"` at once.
This is the difference to expect when moving between embedded and deployed --
see [SDKs](/basics/sdk).
diff --git a/docs/web/curation/aggregate.mdx b/docs/web/curation/aggregate.mdx
index 91c32fdd4..d06fdfaad 100644
--- a/docs/web/curation/aggregate.mdx
+++ b/docs/web/curation/aggregate.mdx
@@ -4,11 +4,14 @@ sidebarTitle: "Aggregate"
description: "Counting, grouping and summarizing — finding out what your data actually contains."
icon: chart-column
keywords: ["aggregate", "group by", "class balance", "count", "profiling", "distinct"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ Aggregation is SQL, which runs on an Enterprise deployment with SQL
+ enabled; the embedded library does not run SQL.
---
-Enterprise Aggregation is SQL, and
-[SQL needs a deployment](/basics/sql#sql-is-remote).
-
Before curating anything, find out what you have. Most of the surprises in a
training set — a class that is 90% of the rows, a column that is half null, a
"unique" id that is not — are one `GROUP BY` away from being visible.
diff --git a/docs/web/curation/index.mdx b/docs/web/curation/index.mdx
index 0bfc89b2d..0b68d0504 100644
--- a/docs/web/curation/index.mdx
+++ b/docs/web/curation/index.mdx
@@ -15,8 +15,8 @@ reach for it, and links to the [SQL reference](/sql) for the complete syntax.
Most curation is analytical -- grouping, joining, ranking -- which the query
-builders do not do. It is therefore SQL, and SQL needs a deployment. See
-[SQL](/basics/sql#sql-is-remote).
+builders do not do. It is therefore SQL, and SQL needs a deployment with its
+SQL endpoint enabled. See [SQL](/basics/sql#sql-is-remote).
## The four questions {#questions}
@@ -52,3 +52,6 @@ you ended up with.
A curated result you want to keep is a
[materialized view](/management/materialized-view) -- stored, refreshed, and
readable by a [data loader](/training/data-loading) like any other table.
+Keeping a joined or windowed result this way takes SQL's
+`CREATE MATERIALIZED VIEW` on a deployment that enables materialized views; the
+SDK's `create_materialized_view` reads a single table.
diff --git a/docs/web/curation/join.mdx b/docs/web/curation/join.mdx
index b4c198ef9..846e2cae9 100644
--- a/docs/web/curation/join.mdx
+++ b/docs/web/curation/join.mdx
@@ -4,11 +4,14 @@ sidebarTitle: "Join"
description: "Bringing labels, metadata and scores together with the rows they describe."
icon: link
keywords: ["join", "labels", "metadata", "enrichment", "namespace"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ Joins are SQL, which runs on an Enterprise deployment with SQL enabled;
+ the embedded library does not run SQL.
---
-Enterprise Joins are SQL, and
-[SQL needs a deployment](/basics/sql#sql-is-remote).
-
Curation usually means combining things that were produced separately — images
in one table, human labels in another, model scores in a third. A join is how
they become one dataset.
@@ -62,9 +65,10 @@ ORDER BY hits DESC
```
-Vector search has no SQL form, so a similarity result cannot be joined this way.
-Run the search in an SDK, then join over its output — or write the result to a
-table first.
+Whether SQL can express vector search
+[depends on the deployment](/basics/sql#no-vector-sql). Where it cannot, run the
+search in an SDK, then join over its output — or write the result to a table
+first.
## Making it fast {#performance}
diff --git a/docs/web/curation/sampling.mdx b/docs/web/curation/sampling.mdx
index 4e8b000cd..54f9d12f9 100644
--- a/docs/web/curation/sampling.mdx
+++ b/docs/web/curation/sampling.mdx
@@ -4,6 +4,13 @@ sidebarTitle: "Sampling"
description: "Drawing a subset you can afford to work with, and fixing it when it has to be reproducible."
icon: dice
keywords: ["sampling", "tablesample", "subset", "eval set", "reproducible", "shuffle"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ `TABLESAMPLE` is SQL, which runs on an Enterprise deployment with SQL
+ enabled. Shuffled reads for training work in both through the SDK; see
+ [Shuffling for training](#training).
---
Most curation starts with a subset. A question you can answer in ten seconds on
@@ -79,7 +86,7 @@ smaller result.
## Shuffling for training {#training}
For a training loop rather than a query, the SDKs read a table in a shuffled
-order without SQL at all:
+order without SQL at all, in the embedded library and on a deployment alike:
```python
from lancedb.permutation import Permutation
diff --git a/docs/web/curation/windowing.mdx b/docs/web/curation/windowing.mdx
index fbb3cbbf2..2e8bcc30f 100644
--- a/docs/web/curation/windowing.mdx
+++ b/docs/web/curation/windowing.mdx
@@ -4,11 +4,14 @@ sidebarTitle: "Windowing"
description: "Picking one row per thing, ranking within a group, and splitting a dataset."
icon: chart-simple
keywords: ["window", "deduplication", "row_number", "rank", "train test split", "per class"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ Window functions are SQL, which runs on an Enterprise deployment with
+ SQL enabled; the embedded library does not run SQL.
---
-Enterprise Window functions are SQL, and
-[SQL needs a deployment](/basics/sql#sql-is-remote).
-
A window function computes across a set of related rows and returns a value
**per row** — nothing is collapsed. That is what makes it the tool for "which of
these do I keep", where an aggregate would throw away the rows you are choosing
diff --git a/docs/web/feature-engineering/add-computed-column.mdx b/docs/web/feature-engineering/add-computed-column.mdx
index 571797d4e..afb53eba3 100644
--- a/docs/web/feature-engineering/add-computed-column.mdx
+++ b/docs/web/feature-engineering/add-computed-column.mdx
@@ -4,6 +4,12 @@ sidebarTitle: "Computed Columns"
description: "Declare a column from a SQL expression. Nothing is evaluated until you refresh it."
icon: table-columns
keywords: ["computed columns", "add_columns", "transforms", "schema"]
+availability:
+ oss: available
+ enterprise: varies
+ summary: >-
+ Computed columns work in the embedded library. On a deployment they are off
+ by default and have to be enabled there.
---
A computed column is declared with an expression and starts with no values.
@@ -33,7 +39,8 @@ including that you can travel back to before the column existed.
- **SQL expressions in `transforms`** are evaluated *now*, for every row, as
part of the call. Good for a small table, or a column you want populated
immediately. A `FunctionApplication` passed through `transforms` instead
- declares empty Function-bound columns; a refresh fills them.
+ declares empty Function-bound columns, which a refresh fills; that needs a
+ deployment with Functions enabled, and the embedded library refuses it.
- **`computed`** stores the expression and evaluates nothing. The column is
committed empty and filled later by
[`refresh_column`](/feature-engineering/refresh-column).
@@ -77,7 +84,8 @@ reshape later. Dropping the computed column releases the constraint.
When the value cannot be expressed in SQL -- an embedding, a model call, an
image decode -- the column is filled by a registered
[function](/management/function) instead of an expression. Declaring it looks
-the same; what differs is what fills it.
+the same; what differs is what fills it. It needs a deployment with Functions
+enabled.
## What to read next {#next}
diff --git a/docs/web/feature-engineering/data-evolution.mdx b/docs/web/feature-engineering/data-evolution.mdx
index 5f50bdcbb..b568c8c16 100644
--- a/docs/web/feature-engineering/data-evolution.mdx
+++ b/docs/web/feature-engineering/data-evolution.mdx
@@ -4,6 +4,12 @@ sidebarTitle: "Data Evolution"
description: "Derive new columns from data already in the table, without rewriting what is already there."
icon: wand-magic-sparkles
keywords: ["data evolution", "derived columns", "add_columns", "zero copy", "feature engineering"]
+availability:
+ oss: available
+ enterprise: available
+ summary: >-
+ Adding columns computed from SQL expressions works in the embedded library
+ and on a deployment.
---
import {
@@ -27,7 +33,7 @@ column -- the existing data, which is the expensive part on a multimodal table,
is never rewritten. See [why that works](/basics/lance#evolution).
-In SQL this is [`ALTER TABLE ... ADD COLUMN ... AS`](/sql/ddl/table#computed-column).
+In SQL, on a deployment that enables computed columns, this is [`ALTER TABLE ... ADD COLUMN ... AS`](/sql/ddl/table#computed-column).
## Set up the example table {#set-up-the-example-table}
@@ -105,6 +111,8 @@ exist when that does not fit:
- A [function](/management/function) fills a column with Python, for values SQL
cannot express -- an embedding, a model call, an image decode.
+On a deployment, both have to be enabled there.
+
## What to read next {#next}
diff --git a/docs/web/feature-engineering/index.mdx b/docs/web/feature-engineering/index.mdx
index 4b8200d40..cc454990d 100644
--- a/docs/web/feature-engineering/index.mdx
+++ b/docs/web/feature-engineering/index.mdx
@@ -17,7 +17,7 @@ versioned, and refreshed like anything else, not a separate system bolted
alongside.
-Every operation here has a SQL form -- see [DDL](/sql/ddl/table#alter) to declare a column and [REFRESH](/sql/dml/refresh) to fill it.
+On a deployment, every operation here also has a SQL form -- see [DDL](/sql/ddl/table#alter) to declare a column and [REFRESH](/sql/dml/refresh) to fill it.
## The shape everything shares {#the-shape}
@@ -46,9 +46,9 @@ idempotent and cheap -- but it will surprise you if you expect a spreadsheet.
| | What it produces | Filled by | Available |
| --- | --- | --- | --- |
-| [Computed column](/feature-engineering/add-computed-column) | a new column on an existing table | a SQL expression | everywhere |
-| [Materialized view](/feature-engineering/materialized-views) | a new table derived by a query | a refresh | everywhere |
-| [Function](/management/function) | a computed column filled by Python | registered code | Enterprise |
+| [Computed column](/feature-engineering/add-computed-column) | a new column on an existing table | a SQL expression | embedded, and deployments that enable it |
+| [Materialized view](/feature-engineering/materialized-views) | a new table derived by a query | a refresh | embedded, and deployments that enable it |
+| [Function](/management/function) | a computed column filled by Python | registered code | Enterprise deployments that enable it |
**Computed columns** are the common case: a column declared with a SQL
expression, filled by [a refresh](/feature-engineering/refresh-column).
diff --git a/docs/web/feature-engineering/refresh-column.mdx b/docs/web/feature-engineering/refresh-column.mdx
index d0f9f06a3..69515e7e9 100644
--- a/docs/web/feature-engineering/refresh-column.mdx
+++ b/docs/web/feature-engineering/refresh-column.mdx
@@ -4,6 +4,12 @@ sidebarTitle: "Column Refresh"
description: "Fill the rows of a computed column that lack values — in process, or as a server-side job."
icon: arrows-rotate
keywords: ["refresh_column", "backfill", "job", "idempotent", "REFRESH COLUMN"]
+availability:
+ oss: available
+ enterprise: varies
+ summary: >-
+ In the embedded library a refresh runs in your process. On a deployment it
+ runs as a server job, which has to be enabled there.
---
A [declared column](/feature-engineering/add-computed-column) starts empty. A
@@ -72,7 +78,8 @@ REFRESH COLUMN embedding ON documents WHERE created_at > '2026-01-01'
Enterprise
-Against a deployment the refresh runs on the cluster. `refresh_column` raises
+Against a deployment that enables computed columns, the refresh runs on the
+cluster. `refresh_column` raises
there; use `refresh_column_async`, which returns a [job](/basics/jobs) you can
wait on or poll instead of holding a connection open:
diff --git a/docs/web/management/database.mdx b/docs/web/management/database.mdx
index 1f77e5b10..966f80c6c 100644
--- a/docs/web/management/database.mdx
+++ b/docs/web/management/database.mdx
@@ -4,6 +4,13 @@ sidebarTitle: "Database"
description: "Connecting to LanceDB: the URI forms, their options, and what each one changes."
icon: database
keywords: ["connect", "database", "uri", "api key", "storage options", "consistency"]
+availability:
+ oss: available
+ enterprise: available
+ summary: >-
+ The embedded library connects to a local directory or object storage, and
+ a `db://` URI connects to a deployment. Which operations exist depends on
+ the connection, as the table below shows.
---
A database is the root of a [catalog](/basics/catalog). A connection opens
@@ -40,10 +47,10 @@ storage and does the work itself. The third talks to a **deployment**.
| --- | --- | --- |
| Where queries run | in your process | on the server |
| Table handle | `LanceTable` | `RemoteTable` |
-| [SQL](/basics/sql) | -- | yes |
+| [SQL](/basics/sql) | -- | where enabled |
| Server-side [jobs](/basics/jobs) | -- | yes |
-| [Functions](/management/function) | -- | yes |
-| [Authorization](/governance/authorization) | storage permissions | granted per object |
+| [Functions](/management/function) | -- | where enabled |
+| [Authorization](/governance/authorization) | storage permissions | granted per object, where configured |

@@ -132,9 +139,11 @@ const db = await lancedb.connect(uri, { readConsistencyInterval: 5 });
```
-The default reads a snapshot taken when the table was opened, so a long-lived
-connection **will not see other processes' writes** until it reopens the table.
-That is the right default for a batch job and the wrong one for a service.
+In the embedded library, the default reads a snapshot taken when the table was
+opened, so a long-lived connection **will not see other processes' writes**
+until it reopens the table. That is the right default for a batch job and the
+wrong one for a service. On a deployment, reads follow the deployment's own
+freshness setting, which the interval can only tighten.
Set it when several processes write the same table and readers must observe
those writes. The cost is a metadata check on that interval. See
@@ -146,8 +155,8 @@ those writes. The cost is a metadata check on that interval. See
| --- | --- | --- | --- |
| list tables | `table_names`, `list_tables` | `tableNames`, `listTables` | -- |
| the URI it opened | `uri` | `display()` | -- |
-| drop every table | `drop_all_tables` | `dropAllTables` | -- |
-| drop the database | `drop_database` | -- | -- |
+| drop every table, embedded only | `drop_all_tables` | `dropAllTables` | -- |
+| drop the database, embedded only | `drop_database` | -- | -- |
| close | -- | `close`, `isOpen` | -- |
diff --git a/docs/web/management/function.mdx b/docs/web/management/function.mdx
index 40e5bcd00..4a24e0ec5 100644
--- a/docs/web/management/function.mdx
+++ b/docs/web/management/function.mdx
@@ -4,6 +4,12 @@ sidebarTitle: "Function"
description: "Register a Python function once and apply it as a column, for work SQL cannot express."
icon: code
keywords: ["udf", "functions", "create_function", "embedding", "feature engineering"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ Functions run on a LanceDB Enterprise deployment that has them enabled; the
+ embedded library cannot register or run them.
---
import {
@@ -17,14 +23,13 @@ import {
PyFunctionInspect as FunctionInspect,
} from '/snippets/function.mdx';
-Enterprise
-
Some columns cannot be written as a SQL expression: an embedding, a model call,
an image decode. A function is a Python callable registered with the database,
versioned, and then applied as a column — the code runs where the data is
rather than pulling rows to your process.
-Registering and running a function needs a LanceDB Enterprise connection. On a
+Registering and running a function needs a LanceDB Enterprise deployment with
+Functions enabled, which they are not by default. On a
local connection `create_function` raises `NotImplementedError`; to derive a
column locally, declare a
[SQL computed column](/feature-engineering/add-computed-column) instead.
@@ -212,6 +217,10 @@ the name was already gone. Deleting the object's content can finish after the
call returns, as a [background job](/maintenance/background-jobs).
`drop_function_async` returns that job with the result, so you can wait for it.
+A deployment refuses the drop unless it also allows changes to a function's
+lifecycle, which is a separate setting, off by default even where Functions are
+enabled.
+
## What to read next {#next}
diff --git a/docs/web/management/index.mdx b/docs/web/management/index.mdx
index 1d4d4eeba..a1a2cde13 100644
--- a/docs/web/management/index.mdx
+++ b/docs/web/management/index.mdx
@@ -16,7 +16,7 @@ Operations that can take a while have an `_async` form returning a
## The surface at a glance {#surface}
-SQL requires a deployment -- a local database has no engine to plan a statement.
+SQL requires a deployment that enables its SQL endpoint -- a local database has none.
See [SQL](/basics/sql#sql-is-remote).
@@ -71,11 +71,12 @@ it current.
| | Python | TypeScript | SQL |
| --- | --- | --- | --- |
-| create | -- | -- | `CREATE VIEW` |
-| drop | -- | -- | `DROP VIEW` |
+| create | `create_view` | `createView` | `CREATE VIEW` |
+| list | `list_views` | `listViews` | -- |
+| drop | `drop_view`, `drop_view_async` | `dropView`, `dropViewAsync` | `DROP VIEW` |
-Enterprise Views exist only in SQL -- there is no SDK
-method for them, because the thing a view stores *is* a SQL statement. See
+Enterprise Views exist only on a deployment that
+enables them; the SDK methods send the view's SQL query to the deployment. See
[Views](/management/view).
### Functions {#functions}
@@ -87,8 +88,9 @@ method for them, because the thing a view stores *is* a SQL statement. See
| list | `list_functions` | -- | `SHOW FUNCTIONS` |
| drop | `drop_function` | -- | -- |
-Enterprise A function runs on the server, so there is
-no local form. The TypeScript SDK has no function methods; use Python or SQL.
+Enterprise A function runs on the server, and only on
+a deployment that enables functions, so there is no local form. The TypeScript
+SDK has no function methods; use Python or SQL.
See [Functions](/management/function).
### Jobs {#jobs}
diff --git a/docs/web/management/materialized-view.mdx b/docs/web/management/materialized-view.mdx
index cbdb703b1..8216b3fc2 100644
--- a/docs/web/management/materialized-view.mdx
+++ b/docs/web/management/materialized-view.mdx
@@ -4,6 +4,14 @@ 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"]
+availability:
+ oss: available
+ enterprise: varies
+ summary: >-
+ Materialized views are created and managed in the embedded library. On a
+ deployment they are off by default and have to be enabled, and the SDK
+ creates them through the deployment's SQL endpoint; see
+ [Against a deployment](#deployment).
---
A materialized view is a table whose contents are defined by a query over
@@ -41,8 +49,8 @@ const view = await db.createMaterializedView("recent_docs", "documents", {
`source` names the table it derives from. A local source does not need stable
-row ids or any other storage option; a deployment may require stable row ids
-(see [Against a deployment](#deployment)). `select`, `where` and `limit` record
+row ids or any other storage option; an earlier deployment version may require
+stable row ids (see [Against a deployment](#deployment)). `select`, `where` and `limit` record
the query -- there is no separate definition step.
## Opening, listing and dropping {#manage}
@@ -78,9 +86,10 @@ rows. Both are properties; on an async view, the definition is read with
Enterprise `create_materialized_view` works on a
`db://` connection as well as a local one. There the SDK creates and refreshes
the view through SQL, and the work runs on the cluster rather than in your
-process. Materialized views are off by default on a deployment and have to be
-enabled there, and a deployment may require a view's source to have stable row
-ids; see
+process, so the deployment's [SQL endpoint](/basics/sql#sql-is-remote) has to be
+reachable. Materialized views are off by default on a deployment and have to be
+enabled there, and an earlier deployment version may require a view's source to
+have stable row ids; see
[Against a deployment](/feature-engineering/materialized-views#availability).
## What to read next {#next}
diff --git a/docs/web/management/namespace.mdx b/docs/web/management/namespace.mdx
index f1310b6da..b9b014e9f 100644
--- a/docs/web/management/namespace.mdx
+++ b/docs/web/management/namespace.mdx
@@ -4,6 +4,12 @@ sidebarTitle: "Namespace"
description: "Grouping tables into a hierarchy, and addressing them through it."
icon: folder-tree
keywords: ["namespace", "catalog", "hierarchy", "directory namespace", "rest namespace"]
+availability:
+ oss: available
+ enterprise: available
+ summary: >-
+ Namespaces work in the embedded library, through directory or REST
+ catalogs, and on a deployment.
---
import {
@@ -29,7 +35,7 @@ language: Python uses `namespace_path`, Rust uses builder methods like `.namespa
TypeScript uses `namespacePath` arguments.
-In SQL a namespaced table is addressed as a [dotted path](/sql/dql/select#namespaces).
+In SQL on a deployment, a namespaced table is addressed as a [dotted path](/sql/dql/select#namespaces).
## Namespace hierarchy {#namespace-hierarchy}
@@ -227,7 +233,8 @@ let db = lancedb::connect_namespace("rest", properties)
```
[LanceDB Enterprise](/enterprise) operates a REST namespace server on top of the Lance format, so any REST client that can speak the REST namespace API
-contract can be used to interact with it. For authentication examples in LanceDB Enterprise, visit
+contract can be used to interact with it. It does not serve the contract's `exists` routes, so checks such as `namespace_exists`
+fail against it. For authentication examples in LanceDB Enterprise, visit
the [Namespaces in SDKs](#namespaces-in-lancedb-enterprise) page.
## Best practices {#best-practices}
diff --git a/docs/web/management/view.mdx b/docs/web/management/view.mdx
index bfb3a0543..d9683ea26 100644
--- a/docs/web/management/view.mdx
+++ b/docs/web/management/view.mdx
@@ -4,14 +4,14 @@ sidebarTitle: "View"
description: "A saved query, evaluated when read. The non-materialized counterpart to a materialized view."
icon: eye
keywords: ["view", "create view", "sql", "catalog"]
+availability:
+ oss: unavailable
+ enterprise: varies
+ summary: >-
+ Views need a LanceDB Enterprise deployment that has them enabled; the
+ embedded library cannot create them.
---
-Enterprise
-
-This page describes a LanceDB Enterprise capability. The embedded form
-of LanceDB has no server to provide it -- see
-[Architecture](/architecture) for what differs between the two.
-
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.
@@ -27,6 +27,8 @@ defined by a query; the difference is entirely when that query runs.
| Read cost | the full query, every read | a table scan |
| Write cost | none | a refresh |
-Views are created in SQL, over the [Flight SQL endpoint](/sql#connecting) --
-there is no SDK method, because the thing a view stores *is* a SQL statement.
-See [View](/sql/ddl/view) for `CREATE VIEW`, `DROP VIEW`, and listing.
+Views are created on a deployment, either in SQL over the
+[Flight SQL endpoint](/sql#connecting) or with the SDKs' `create_view` /
+`createView`, which send the query to the deployment. Either way, the deployment
+must have views enabled. See [View](/sql/ddl/view) for `CREATE VIEW`,
+`DROP VIEW`, and listing.