fix(python): implement remote namespace and table existence checks (#4725)

Remote Python connections inherited the unsupported-operation stubs for
`namespace_exists` and `table_exists`, so both raised
`NotImplementedError` even when namespace and table operations worked.

Add the missing remote overrides, async methods, and PyO3 bindings using
the existing namespace describe and table open paths. Only an explicit
not-found result returns `False`; permission, transport, and server
errors propagate. This preserves authentication, dynamic headers,
retries, and nested namespace handling, and rechecks cached tables
before reporting that they exist.

The async namespace helper also recognizes native `NamespaceNotFound`
errors so missing local namespaces return `False`. The table and
namespace guides document Python remote support and distinguish it from
the unsupported `exists` routes used by direct REST namespace clients.

Validation:
- All 40 focused regression cases pass, covering successful and missing
lookups, local and remote namespaces, dynamic headers, permission/server
errors, invalid table identifiers, and cached tables that disappear.
- The original inherited stubs reproduce the reported
`NotImplementedError`; the local namespace regression reproduced the
native missing-namespace `RuntimeError` before its fix.
- Full remote connection suite: 255 passed. Local namespace tests: 14
passed.
- `cargo clippy --quiet -p lancedb-python --features remote --lib`,
`cargo fmt --all`, Python Ruff lint, and Python formatting checks pass.
- Root `ruff check .` reports 48 existing errors in documentation
examples under `docs/web-tests`; the Python subtree passes and those
unrelated files are unchanged.

Fixes #4722

<!-- lance-gatekeeper-fix:v1 agent=4d369a0681756fdb5a8b35853d7f5607
generation=1 -->

---------

Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
This commit is contained in:
lancedb-gatefixer[bot]
2026-10-28 16:08:43 -07:00
committed by GitHub
parent fc5170cbed
commit 741cb9ad4e
8 changed files with 257 additions and 11 deletions
+5 -2
View File
@@ -243,8 +243,11 @@ let db = lancedb::connect_namespace("rest", properties)
```
</CodeGroup>
[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. 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
contract can be used to interact with it. It does not serve the contract's `exists` routes,
so existence checks made through a direct REST namespace client fail against it.
Python remote connections created with `lancedb.connect("db://...")` or
`lancedb.connect_async("db://...")` support `namespace_exists` and `table_exists`
through the existing describe routes instead. For authentication examples in LanceDB Enterprise, visit
the [Namespaces in SDKs](#namespaces-in-lancedb-enterprise) page.
## Best practices {#best-practices}
+15 -8
View File
@@ -214,14 +214,21 @@ await db.tableNames();
Each accepts `namespace_path` to act inside a [namespace](/management/namespace)
rather than at the database root.
To find out whether a table exists, open it and handle the error, or look for
its name in a listing. A missing table raises `ValueError` on a local directory
or a deployment, and `lance_namespace.TableNotFoundError` on a connection from
`connect_namespace`. A listing returns one page of names at a time, so check
every page. Python's `table_exists` is no substitute: a local directory or a
deployment raises `NotImplementedError` for it, and on a connection from
`connect_namespace("dir", ...)` or `connect_namespace("rest", ...)` it fails with
an `AttributeError`. TypeScript has no `tableExists`.
For Python remote connections created with `lancedb.connect("db://...")`, use
`db.table_exists(["documents"])` to check whether a table exists. For an async
remote connection, use `await db.table_exists(["documents"])`. Include namespace
segments before the table name, for example `["analytics", "documents"]`. These
checks return `False` when the table is missing and propagate other errors,
including permission errors.
Local synchronous directory connections still raise `NotImplementedError` for
`table_exists`. On a connection from `connect_namespace("dir", ...)` or
`connect_namespace("rest", ...)`, it fails with an `AttributeError`. For these
connections, open the table and handle the error, or look for its name in a
listing. A missing table raises `ValueError` on a local directory and
`lance_namespace.TableNotFoundError` on a connection from `connect_namespace`.
A listing returns one page of names at a time, so check every page. TypeScript
has no `tableExists`.
## Rename and clone tables {#rename-clone}