diff --git a/docs/api-reference/index.mdx b/docs/api-reference/index.mdx index d3e5168..2607aa9 100644 --- a/docs/api-reference/index.mdx +++ b/docs/api-reference/index.mdx @@ -10,6 +10,9 @@ refer to the API documentation linked below. If you're looking for a REST API reference, visit the [REST API](/api-reference/rest) page. +If you're looking for conceptual and practical namespace guidance before diving into method signatures, see +[Namespaces and Catalog Model](/namespaces) and [Using Namespaces in SDKs](/tables/namespaces). + ## Supported SDKs Python, Typescript and Rust SDKs are officially supported by LanceDB. @@ -29,4 +32,3 @@ Other language SDKs are available through examples or third-party contributions. | [Java API Quickstart]https://lancedb.github.io/lancedb/java/java/)| Streamline REST API interactions in Java| {/* TODO: Add Go bindings reference page here */} - diff --git a/docs/docs.json b/docs/docs.json index a30abbd..e495e22 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -40,7 +40,7 @@ "pages": [ "index", "lance", - "features" + "namespaces" ] }, { @@ -80,6 +80,7 @@ "tables/multimodal", "tables/schema", "tables/update", + "tables/namespaces", "tables/versioning", "tables/consistency" ] @@ -383,4 +384,4 @@ "destination": "tutorials/search/:slug*" } ] -} \ No newline at end of file +} diff --git a/docs/features.mdx b/docs/features.mdx deleted file mode 100644 index 6c5c1b9..0000000 --- a/docs/features.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Feature catalog" -sidebarTitle: "Feature catalog" -description: "An outline of all the features offered by LanceDB, across its open source, cloud, and enterprise offerings." -icon: "grip-vertical" -mode: "wide" ---- - -## Storage - -LanceDB provides flexible storage backends that support both cloud object storage and local high-performance storage for different deployment scenarios. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Object, File, Block Storage](/storage/) | Support for AWS, GCS, Azure and S3-compatible vendors. | ✅ | ✅ | ✅ | -| [Local SSD/NVMe Storage](/storage/) | Support for storage on customer's custom servers. | ✅ | | ✅ | - -## Tables - -LanceDB's table abstraction provides ACID-compliant data management with schema evolution, versioning, and consistency guarantees for vector and scalar data. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Tables - CRUD Operations](/tables/) | Basic API to create, read, update, drop tables. | ✅ | ✅ | ✅ | -| [Tables - Data Evolution](/tables/schema/) | Alter column schema, datatype, backfill + merge data | ✅ | ✅ | ✅ | -| [Tables - Versioning](/tables/versioning/) | Append, overwrite, check versions + tag them. | ✅ | ✅ | ✅ | -| [Tables - Consistency](/tables/consistency/) | Synchronize database with underlying storage. | ✅ | ✅ | ✅ | - -## Ingestion - -LanceDB's ingestion pipeline handles both vector embedding generation and data loading with support for multiple formats and efficient batch operations. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Embedding - Text Data](/embedding/) | Generate vector embeddings from text data using various embedding models. | ✅ | ✅ | ✅ | -| [Embedding - Multimodal Data](/embedding/) | Generate embeddings from images, audio, and other multimodal content. | ✅ | ✅ | ✅ | -| [Embedding - CPU & GPU Device Configuration](/embedding/) | Configure CPU or GPU acceleration for embedding generation performance. | ✅ | ✅ | ✅ | -| [Embedding - Environment Variables](/embedding/) | Manage API keys and configuration for embedding model access. | ✅ | ✅ | ✅ | -| [Data Ingestion - Default](/tables/create/) | Formerly called Adding Data to a Table. | ✅ | ✅ | ✅ | -| [Data Ingestion - Formats](/tables/create/) | Pandas, Polars, Pyarrow, Pydantic | ✅ | ✅ | ✅ | -| [Data Ingestion - Upsert](/tables/update/) | Update existing records or insert new ones based on key. | ✅ | ✅ | ✅ | -| [Data Ingestion - Merge Insert](/tables/update/) | Combine data from multiple sources into a single table. | ✅ | ✅ | ✅ | - -## Indexing - -LanceDB's indexing system provides multiple vector and scalar index types with automated optimization for fast similarity search and retrieval operations. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Vector Index - IVF_FLAT](/indexing/vector-index/) | Minimal index that looks at IVF partitions, instead of brute forcing. | ✅ | ✅ | ✅ | -| [Vector Index - IVF_PQ](/indexing/vector-index/) | Default vector index using Euclidean distance. | ✅ | ✅ | ✅ | -| [Vector Index - IVF_SQ](/indexing/vector-index/) | IVF index built using scalar quantized vectors. | ✅ | ✅ | ✅ | -| [Vector Index - IVF_HNSW_SQ](/indexing/vector-index/) | HNSW built on IVF's partitions + vectors that are scalar quantized. | ✅ | ✅ | ✅ | -| [Vector Index - Binary](/indexing/vector-index/) | IVF_FLAT with Hamming distance for binary vectors. | ✅ | ✅ | ✅ | -| [Scalar Index](/indexing/scalar-index/) | BTREE, BITMAP, LABEL_LIST | ✅ | ✅ | ✅ | -| [Automated Indexing](/indexing/vector-index/) | Indexing happens in the background no config. | | ✅ | ✅ | -| [Bypass Automated Indexing](/indexing/) | When you want to search over all available vectors. | ✅ | ✅ | ✅ | -| [Reindexing - Manual](/indexing/reindexing/) | User needs to specify that they want to reindex. | ✅ | ✅ | ✅ | -| [Reindexing - Automated](/indexing/reindexing/) | Reindexing happens in the background no config | | ✅ | ✅ | -| [GPU Indexing - Manual](/indexing/gpu-indexing/) | User needs to specify which indexing device to use. | ✅ | ✅ | ✅ | -| [GPU Indexing - Automated](/indexing/gpu-indexing/) | Indexing device is automatically set for user. | | ✅ | ✅ | -| [Full Text Search Index](/indexing/fts-index/) | Inverted index | ✅ | ✅ | ✅ | - -## Search - -LanceDB's search capabilities combine vector similarity search, full-text search, and hybrid approaches to provide comprehensive retrieval functionality across different data types. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Vector Search - No Index](/search/vector-search/) | Goes through all the available vectors. | ✅ | ✅ | ✅ | -| [Vector Search - ANN Index](/search/vector-search/) | Retrieves top K similar vectors. | ✅ | ✅ | ✅ | -| [Vector Search - Multivectors](/search/multivector-search/) | Late interaction vector search. | ✅ | ✅ | ✅ | -| [Vector Search - Distance Range](/search/vector-search/) | Search for vectors within a specific distance threshold. | ✅ | ✅ | ✅ | -| [Vector Search - Binary Vectors](/search/vector-search/) | Search using binary vector representations for efficiency. | ✅ | ✅ | ✅ | -| [Vector Search - Filtering](/search/filtering/) | Apply scalar filters during vector search operations. | ✅ | ✅ | ✅ | -| [Vector Search - Batch API](/search/vector-search/) | Process multiple search queries in a single request. | ✅ | ✅ | ✅ | -| [Vector Search - Async Indexing](/search/vector-search/) | Fallback brute force for fast performance. | | ✅ | ✅ | -| [Full Text Search - FTS Index](/search/full-text-search/) | Inverted Index | ✅ | ✅ | ✅ | -| [Full Text Search - Tokenizer](/search/full-text-search/) | Ngram and other common methods of splitting text data. | ✅ | ✅ | ✅ | -| [Full Text Search - Scalar Index](/search/full-text-search/) | BTREE, BITMAP, LABEL_LIST for non-vector data. | ✅ | ✅ | ✅ | -| [Full Text Search - Fuzzy Search](/search/full-text-search/) | Searching when there is a typo on the query. | ✅ | ✅ | ✅ | -| [Full Text Search - Prefix Matching](/search/full-text-search/) | Search for text that starts with specific characters. | ✅ | ✅ | ✅ | -| [Full Text Search - Score Boosting](/search/full-text-search/) | Increase relevance scores for specific terms or fields. | ✅ | ✅ | ✅ | -| [Full Text Search - Boolean Logic](/search/full-text-search/) | Use AND, OR, NOT operators in text search queries. | ✅ | ✅ | ✅ | -| [Full Text Search - Array Fields](/search/full-text-search/) | Search within array or list data types. | ✅ | ✅ | ✅ | -| [Hybrid Search - FTS Index](/search/hybrid-search/) | Combine vector and full-text search in single query. | ✅ | ✅ | ✅ | -| [Hybrid Search - Reranking](/search/hybrid-search/) | Reorder search results using additional ranking models. | ✅ | ✅ | ✅ | -| [SQL Queries](/search/sql) | Execute standard SQL queries on LanceDB tables. | ✅ | ✅ | ✅ | -| [Query Optimization](/search/optimize-queries/) | Explain query plan, analyze query plan, optimization config settings. | ✅ | ✅ | ✅ | - -## Filtering - -LanceDB's filtering system provides flexible query capabilities that can be applied independently or in combination with vector and full-text search operations. - -| Feature | Description | OSS | Cloud | Enterprise | -|:---|:---|:---:|:---:|:---:| -| [Filtering - no Vector Search](/search/filtering/) | Apply filters without vector search operations. | ✅ | ✅ | ✅ | -| [Filtering - Vector Search](/search/filtering/) | Apply filters during vector search operations. | ✅ | ✅ | ✅ | -| [Filtering - Full Text Search](/search/filtering/) | Apply filters during full-text search operations. | ✅ | ✅ | ✅ | \ No newline at end of file diff --git a/docs/namespaces.mdx b/docs/namespaces.mdx new file mode 100644 index 0000000..03ab60d --- /dev/null +++ b/docs/namespaces.mdx @@ -0,0 +1,74 @@ +--- +title: "Namespaces and the Catalog Model" +sidebarTitle: "Namespaces" +description: "Understand LanceDB as a catalog-level abstraction over Lance's table format, and learn how namespaces help organize Lance tables." +icon: "sitemap" +keywords: ["namespace", "catalog", "lance format", "table format", "lancedb"] +--- + +Despite its name, LanceDB is not a "database" in the traditional sense -- it is a **Multimodal Lakehouse** that builds on the table abstraction, +similar to many other lakehouse projects. LanceDB exposes a catalog-level abstraction over the Lance table format, via a *namespace spec*. + +Lance provides the **file** and **table** formats to store and manage your data and indexes. +LanceDB operates at the catalog layer (used to organize, discover, and operate on many Lance tables) +and provides a compute engine on top of the Lance format. + +This is why many SDK methods in LanceDB, like `create_table`, `open_table`, `drop_table`, and +`rename_table`, accept a `namespace` parameter as input. + +## Namespace hierarchy + +Namespaces are generalizations of catalog specs that give platform developers a clean way to present Lance tables in the structures users expect. The diagram below shows how the hierarchy can go beyond a single level. +A namespace can contain a collection of tables, and it can also contain namespaces recursively. + +![](/static/assets/images/namespaces/lance-namespace.png) + +## Root namespace and the familiar `data/` layout + +The simplest namespace model in LanceDB is a single root namespace, often represented by one +directory: + +```bash +/data/ # root namespace +├─ users.lance # table ["users"] in root +└─ orders.lance # table ["orders"] in root +``` + +As a user of LanceDB, you might never notice namespaces at first, because LanceDB exposes the single-level +hierarchy shown above, with hte data being stored in the `data/` directory`, wher the root namespace +is implicit. In alternative setups, you could have multiple namespaces that we won't covere here, +but you can more about them in the [namespace documentation](https://lance.org/format/namespace/) for the Lance format. + +## Best-practice guidance + +- Use the default, single-level root namespace in LanceDB for locally stored, single applications or early-stage projects. +- For remote storage locations, introduce explicit namespaces when multiple teams, environments, or domains share the same catalog. +- Treat namespace paths as stable identifiers (for example `"prod/search"`, `"staging/recs"`). +- Avoid hard-coding object-store table paths in application code -- instead, prefer catalog identifiers + namespaces. + +See the Python example below for how to use namespaces in practice. + +```python Python icon="python" +import lancedb + +# App config: only the catalog endpoint/root is configured once. +db = lancedb.connect("s3://my-lakehouse/catalog") + +# Business identifier + namespace path (stable app-level IDs) +namespace = ["prod", "recommendations"] +table_name = "user_profiles" + +# Good: resolve table through catalog + namespace +table = db.open_table(table_name, namespace=namespace) + +# Bad: Avoid hard-coded physical object-store table paths +# (it's bad for maintainability reasons) +# table = lancedb.connect( +# "s3://my-lakehouse/catalog/prod/recommendations/user_profiles.lance" +# ) +``` + +## SDK usage + +1. For language-specific examples of `namespace` usage across Python, TypeScript, and Rust, see "[Using namespaces in SDKs](/tables/namespaces)". +2. For REST-level operations, see the [REST API Reference](/api-reference/rest). diff --git a/docs/snippets/connection.mdx b/docs/snippets/connection.mdx index bdb202e..0159183 100644 --- a/docs/snippets/connection.mdx +++ b/docs/snippets/connection.mdx @@ -12,15 +12,23 @@ export const PyConnectObjectStorage = "import lancedb\n\nuri = \"s3://your-bucke export const PyConnectObjectStorageAsync = "import lancedb\n\nuri = \"s3://your-bucket/path\"\n# You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\nasync_db = await lancedb.connect_async(uri)\n"; +export const PyNamespaceAdminOps = "import lancedb\n\ndb = lancedb.connect(\"./data/sample-lancedb\")\ndb.create_namespace([\"prod\"])\ndb.create_namespace([\"prod\", \"search\"])\n\nchild_namespaces = db.list_namespaces(namespace=[\"prod\"]).namespaces\nmetadata = db.describe_namespace([\"prod\", \"search\"])\n\ndb.drop_namespace([\"prod\", \"search\"], mode=\"skip\")\ndb.drop_namespace([\"prod\"], mode=\"skip\")\n"; + +export const PyNamespaceTableOps = "import lancedb\n\ndb = lancedb.connect(\"./data/sample-lancedb\")\nnamespace = [\"prod\", \"search\"]\n\ndb.create_table(\n \"users\",\n data=[{\"id\": 1, \"name\": \"alice\"}],\n mode=\"overwrite\",\n namespace=namespace,\n)\n\ntable = db.open_table(\"users\", namespace=namespace)\ntables = db.list_tables(namespace=namespace).tables\n\ndb.drop_table(\"users\", namespace=namespace)\n# drop_all_tables is namespace-aware as well:\n# db.drop_all_tables(namespace=namespace)\n"; + export const TsConnect = "import * as lancedb from \"@lancedb/lancedb\";\n\nasync function connectExample(uri: string) {\n const db = await lancedb.connect(uri);\n return db;\n}\n"; export const TsConnectCloud = "const uri = \"db://your-database-uri\";\nconst apiKey = \"your-api-key\";\nconst region = \"us-east-1\";\n"; export const TsConnectObjectStorage = "async function connectObjectStorageExample() {\n const uri = \"s3://your-bucket/path\";\n // You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\n const db = await lancedb.connect(uri);\n return db;\n}\n"; +export const TsNamespaceTableOps = "const db = await lancedb.connect(uri);\nconst namespace = [\"prod\", \"search\"];\n\nawait db.createTable(\n \"users\",\n [{ id: 1, name: \"alice\" }],\n namespace,\n { mode: \"overwrite\" },\n);\n\nconst table = await db.openTable(\"users\", namespace);\nconst tableNames = await db.tableNames(namespace);\n\nawait db.dropTable(\"users\", namespace);\n// dropAllTables is namespace-aware as well:\n// await db.dropAllTables(namespace);\n"; + export const RsConnect = "async fn connect_example(uri: &str) {\n let db = connect(uri).execute().await.unwrap();\n let _ = db;\n}\n"; export const RsConnectCloud = "let uri = \"db://your-database-uri\";\nlet api_key = \"your-api-key\";\nlet region = \"us-east-1\";\n"; export const RsConnectObjectStorage = "let uri = \"s3://your-bucket/path\";\n// You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\n"; +export const RsNamespaceTableOps = "let conn = connect(uri).execute().await?;\nlet namespace = vec![\"prod\".to_string(), \"search\".to_string()];\n\nlet schema = std::sync::Arc::new(arrow_schema::Schema::new(vec![\n arrow_schema::Field::new(\"id\", arrow_schema::DataType::Int64, false),\n]));\n\nconn.create_empty_table(\"users\", schema)\n .namespace(namespace.clone())\n .execute()\n .await?;\n\nlet _table = conn\n .open_table(\"users\")\n .namespace(namespace.clone())\n .execute()\n .await?;\nlet _table_names = conn\n .table_names()\n .namespace(namespace.clone())\n .execute()\n .await?;\n\nconn.drop_table(\"users\", &namespace).await?;\n// drop_all_tables is namespace-aware as well:\n// conn.drop_all_tables(&namespace).await?;\n"; + diff --git a/docs/snippets/quickstart.mdx b/docs/snippets/quickstart.mdx index 11479ed..d26ea2d 100644 --- a/docs/snippets/quickstart.mdx +++ b/docs/snippets/quickstart.mdx @@ -18,8 +18,6 @@ export const PyQuickstartVectorSearch1Async = "# Let's search for vectors simila export const PyQuickstartVectorSearch2 = "# Let's search for vectors similar to \"wizard\"\nquery_vector = [0.7, 0.3, 0.5]\n\nresults = table.search(query_vector).limit(2).to_polars()\nprint(results)\n"; -export const TsQuickstartOutputPandas = "result = await table.search(queryVector).limit(2).toArray();\n"; - export const TsQuickstartAddData = "const moreData = [\n { id: \"7\", text: \"mage\", vector: [0.6, 0.3, 0.4] },\n { id: \"8\", text: \"bard\", vector: [0.3, 0.8, 0.4] },\n];\n\n// Add data to table\nawait table.add(moreData);\n"; export const TsQuickstartCreateTable = "const data = [\n { id: \"1\", text: \"knight\", vector: [0.9, 0.4, 0.8] },\n { id: \"2\", text: \"ranger\", vector: [0.8, 0.4, 0.7] },\n { id: \"9\", text: \"priest\", vector: [0.6, 0.2, 0.6] },\n { id: \"4\", text: \"rogue\", vector: [0.7, 0.4, 0.7] },\n];\nlet table = await db.createTable(\"adventurers\", data, { mode: \"overwrite\" });\n"; @@ -30,6 +28,8 @@ export const TsQuickstartOpenTable = "table = await db.openTable(\"adventurers\" export const TsQuickstartOutputArray = "result = await table.search(queryVector).limit(2).toArray();\nconsole.table(result);\n"; +export const TsQuickstartOutputPandas = "result = await table.search(queryVector).limit(2).toArray();\n"; + export const TsQuickstartVectorSearch1 = "// Let's search for vectors similar to \"warrior\"\nlet queryVector = [0.8, 0.3, 0.8];\n\nlet result = await table.search(queryVector).limit(2).toArray();\nconsole.table(result);\n"; export const TsQuickstartVectorSearch2 = "// Let's search for vectors similar to \"wizard\"\nqueryVector = [0.7, 0.3, 0.5];\n\nconst results = await table.search(queryVector).limit(2).toArray();\nconsole.table(results);\n"; @@ -49,3 +49,4 @@ export const RsQuickstartOutputArray = "let result: DataFrame = table\n .quer export const RsQuickstartVectorSearch1 = "// Let's search for vectors similar to \"warrior\"\nlet query_vector = [0.8, 0.3, 0.8];\n\nlet result: DataFrame = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .limit(2)\n .select(Select::Columns(vec![\"text\".to_string()]))\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\n"; export const RsQuickstartVectorSearch2 = "// Let's search for vectors similar to \"wizard\"\nlet query_vector = [0.7, 0.3, 0.5];\n\nlet result: DataFrame = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .limit(2)\n .select(Select::Columns(vec![\"text\".to_string()]))\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\nlet text_col = result.column(\"text\").unwrap().str().unwrap();\nlet top_two = vec![\n text_col.get(0).unwrap().to_string(),\n text_col.get(1).unwrap().to_string(),\n];\n"; + diff --git a/docs/static/assets/images/namespaces/lance-namespace.png b/docs/static/assets/images/namespaces/lance-namespace.png new file mode 100644 index 0000000..01573ab Binary files /dev/null and b/docs/static/assets/images/namespaces/lance-namespace.png differ diff --git a/docs/tables/namespaces.mdx b/docs/tables/namespaces.mdx new file mode 100644 index 0000000..97567d0 --- /dev/null +++ b/docs/tables/namespaces.mdx @@ -0,0 +1,74 @@ +--- +title: "Using Namespaces in SDKs" +sidebarTitle: "Namespaces" +description: "Use LanceDB's namespace-aware table and catalog APIs in Python, TypeScript, and Rust." +icon: "folder-tree" +keywords: ["namespace", "create_table", "open_table", "list_tables", "catalog"] +--- + +import { + PyNamespaceTableOps, + PyNamespaceAdminOps, + TsNamespaceTableOps, + RsNamespaceTableOps, +} from '/snippets/connection.mdx'; + +As described in the [Namespaces and Catalog Model](/namespaces) section, "namespaces" are LanceDB's means to generalize catalog specs, providing developers a clean way to manage hierarchical organization of tables in the catalog. The SDKs treat `namespace` as a path and can use it for table resolution when you use LanceDB outside the root namespace. + +As your table organization needs grow with time and your projects become more complex, you can use namespaces to organize your tables in a way that reflects your business domains, teams, or environments. + +## Table operations with namespace paths + +Let's imagine a scenario where your table management needs have evolved, and you now have the following multi-level structure to organize your tables outside the root namespace. +``` +(root) +└── prod + └── search + └── users (table) +``` + +Below, we show how you would express table operations on that namespace. Each item in the namespace +list (`["prod", "search"]`) represents a level in the namespace hierarchy, and the table name is +specified when you create, open or drop it. + + + + {PyNamespaceTableOps} + + + + {TsNamespaceTableOps} + + + + {RsNamespaceTableOps} + + + + +Namespaces are optional parameters in LanceDB, and most basic use cases do not require you to specify them. +An empty namespace (`[]`), which is the default, means "root namespace", and the data will be stored in +the `data/` directory. + + +## Namespace management APIs + +You can open/create/drop tables inside a namespace path (like `["prod", "search"]`). +The Python and Rust SDKs expose namespace lifecycle operations directly. + + + + {PyNamespaceAdminOps} + + + + +In TypeScript, namespace lifecycle management is not on `Connection`, so namespaces usually need to be +created through another admin surface (for example REST/admin tooling) before use. + + +## Related references + +- [Client SDK API references](/api-reference) +- [REST API Reference](/api-reference/rest) +- [Namespaces and the Catalog Model](/namespaces) diff --git a/tests/py/test_connection.py b/tests/py/test_connection.py index 5762f23..7886afa 100644 --- a/tests/py/test_connection.py +++ b/tests/py/test_connection.py @@ -4,6 +4,7 @@ from pathlib import Path import shutil + def test_connection(): # --8<-- [start:connect] import lancedb @@ -53,6 +54,46 @@ def connect_object_storage_config(): return db +def namespace_table_ops_example(): + # --8<-- [start:namespace_table_ops] + import lancedb + + db = lancedb.connect("./data/sample-lancedb") + namespace = ["prod", "search"] + + db.create_table( + "users", + data=[{"id": 1, "name": "alice"}], + mode="overwrite", + namespace=namespace, + ) + + table = db.open_table("users", namespace=namespace) + tables = db.list_tables(namespace=namespace).tables + + db.drop_table("users", namespace=namespace) + # drop_all_tables is namespace-aware as well: + # db.drop_all_tables(namespace=namespace) + # --8<-- [end:namespace_table_ops] + return table, tables + + +def namespace_admin_ops_example(): + # --8<-- [start:namespace_admin_ops] + import lancedb + + db = lancedb.connect("./data/sample-lancedb") + db.create_namespace(["prod"]) + db.create_namespace(["prod", "search"]) + + child_namespaces = db.list_namespaces(namespace=["prod"]).namespaces + metadata = db.describe_namespace(["prod", "search"]) + + db.drop_namespace(["prod", "search"], mode="skip") + db.drop_namespace(["prod"], mode="skip") + # --8<-- [end:namespace_admin_ops] + return child_namespaces, metadata + async def connect_object_storage_config_async(): # --8<-- [start:connect_object_storage_async] import lancedb diff --git a/tests/rs/connection.rs b/tests/rs/connection.rs index a358bcd..bd528a1 100644 --- a/tests/rs/connection.rs +++ b/tests/rs/connection.rs @@ -42,6 +42,38 @@ fn connect_object_storage_config() -> &'static str { uri } +async fn namespace_table_ops_example(uri: &str) -> lancedb::Result<()> { + // --8<-- [start:namespace_table_ops] + let conn = connect(uri).execute().await?; + let namespace = vec!["prod".to_string(), "search".to_string()]; + + let schema = std::sync::Arc::new(arrow_schema::Schema::new(vec![ + arrow_schema::Field::new("id", arrow_schema::DataType::Int64, false), + ])); + + conn.create_empty_table("users", schema) + .namespace(namespace.clone()) + .execute() + .await?; + + let _table = conn + .open_table("users") + .namespace(namespace.clone()) + .execute() + .await?; + let _table_names = conn + .table_names() + .namespace(namespace.clone()) + .execute() + .await?; + + conn.drop_table("users", &namespace).await?; + // drop_all_tables is namespace-aware as well: + // conn.drop_all_tables(&namespace).await?; + // --8<-- [end:namespace_table_ops] + Ok(()) +} + #[allow(dead_code)] fn repo_root() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") diff --git a/tests/ts/connection.test.ts b/tests/ts/connection.test.ts index 8055a94..7d383da 100644 --- a/tests/ts/connection.test.ts +++ b/tests/ts/connection.test.ts @@ -35,4 +35,26 @@ async function connectObjectStorageExample() { } // --8<-- [end:connect_object_storage] -void [uri, apiKey, region, connectObjectStorageExample]; +async function namespaceTableOpsExample(uri: string) { + // --8<-- [start:namespace_table_ops] + const db = await lancedb.connect(uri); + const namespace = ["prod", "search"]; + + await db.createTable( + "users", + [{ id: 1, name: "alice" }], + namespace, + { mode: "overwrite" }, + ); + + const table = await db.openTable("users", namespace); + const tableNames = await db.tableNames(namespace); + + await db.dropTable("users", namespace); + // dropAllTables is namespace-aware as well: + // await db.dropAllTables(namespace); + // --8<-- [end:namespace_table_ops] + return { table, tableNames }; +} + +void [uri, apiKey, region, connectObjectStorageExample, namespaceTableOpsExample];