diff --git a/docs/src/js/classes/Connection.md b/docs/src/js/classes/Connection.md index a21dffba..22b31c06 100644 --- a/docs/src/js/classes/Connection.md +++ b/docs/src/js/classes/Connection.md @@ -131,6 +131,20 @@ Return a brief description of the connection *** +### dropAllTables() + +```ts +abstract dropAllTables(): Promise +``` + +Drop all tables in the database. + +#### Returns + +`Promise`<`void`> + +*** + ### dropTable() ```ts diff --git a/nodejs/__test__/connection.test.ts b/nodejs/__test__/connection.test.ts index d7a6e92a..7fcdb85a 100644 --- a/nodejs/__test__/connection.test.ts +++ b/nodejs/__test__/connection.test.ts @@ -61,6 +61,26 @@ describe("given a connection", () => { await expect(tbl.countRows()).resolves.toBe(1); }); + it("should be able to drop tables`", async () => { + await db.createTable("test", [{ id: 1 }, { id: 2 }]); + await db.createTable("test2", [{ id: 1 }, { id: 2 }]); + await db.createTable("test3", [{ id: 1 }, { id: 2 }]); + + await expect(db.tableNames()).resolves.toEqual(["test", "test2", "test3"]); + + await db.dropTable("test2"); + + await expect(db.tableNames()).resolves.toEqual(["test", "test3"]); + + await db.dropAllTables(); + + await expect(db.tableNames()).resolves.toEqual([]); + + // Make sure we can still create more tables after dropping all + + await db.createTable("test4", [{ id: 1 }, { id: 2 }]); + }); + it("should fail if creating table twice, unless overwrite is true", async () => { let tbl = await db.createTable("test", [{ id: 1 }, { id: 2 }]); await expect(tbl.countRows()).resolves.toBe(2); diff --git a/nodejs/lancedb/connection.ts b/nodejs/lancedb/connection.ts index 6df97185..53ff6aa5 100644 --- a/nodejs/lancedb/connection.ts +++ b/nodejs/lancedb/connection.ts @@ -211,6 +211,11 @@ export abstract class Connection { * @param {string} name The name of the table to drop. */ abstract dropTable(name: string): Promise; + + /** + * Drop all tables in the database. + */ + abstract dropAllTables(): Promise; } /** @hideconstructor */ @@ -336,6 +341,10 @@ export class LocalConnection extends Connection { async dropTable(name: string): Promise { return this.inner.dropTable(name); } + + async dropAllTables(): Promise { + return this.inner.dropAllTables(); + } } /** diff --git a/nodejs/src/connection.rs b/nodejs/src/connection.rs index e6f3183e..49bbf004 100644 --- a/nodejs/src/connection.rs +++ b/nodejs/src/connection.rs @@ -187,4 +187,9 @@ impl Connection { pub async fn drop_table(&self, name: String) -> napi::Result<()> { self.get_inner()?.drop_table(&name).await.default_error() } + + #[napi(catch_unwind)] + pub async fn drop_all_tables(&self) -> napi::Result<()> { + self.get_inner()?.drop_all_tables().await.default_error() + } } diff --git a/python/python/lancedb/db.py b/python/python/lancedb/db.py index c0ffb3a9..d4f30b83 100644 --- a/python/python/lancedb/db.py +++ b/python/python/lancedb/db.py @@ -14,6 +14,7 @@ from overrides import EnforceOverrides, override # type: ignore from lancedb.common import data_to_reader, sanitize_uri, validate_schema from lancedb.background_loop import LOOP +from . import __version__ from ._lancedb import connect as lancedb_connect # type: ignore from .table import ( AsyncTable, @@ -26,6 +27,8 @@ from .util import ( validate_table_name, ) +import deprecation + if TYPE_CHECKING: import pyarrow as pa from .pydantic import LanceModel @@ -294,6 +297,12 @@ class DBConnection(EnforceOverrides): """ raise NotImplementedError + def drop_all_tables(self): + """ + Drop all tables from the database + """ + raise NotImplementedError + @property def uri(self) -> str: return self._uri @@ -486,9 +495,19 @@ class LanceDBConnection(DBConnection): """ LOOP.run(self._conn.drop_table(name, ignore_missing=ignore_missing)) + @override + def drop_all_tables(self): + LOOP.run(self._conn.drop_all_tables()) + + @deprecation.deprecated( + deprecated_in="0.15.1", + removed_in="0.17", + current_version=__version__, + details="Use drop_all_tables() instead", + ) @override def drop_database(self): - LOOP.run(self._conn.drop_database()) + LOOP.run(self._conn.drop_all_tables()) class AsyncConnection(object): @@ -848,9 +867,19 @@ class AsyncConnection(object): if f"Table '{name}' was not found" not in str(e): raise e + async def drop_all_tables(self): + """Drop all tables from the database.""" + await self._inner.drop_all_tables() + + @deprecation.deprecated( + deprecated_in="0.15.1", + removed_in="0.17", + current_version=__version__, + details="Use drop_all_tables() instead", + ) async def drop_database(self): """ Drop database This is the same thing as dropping all the tables """ - await self._inner.drop_db() + await self._inner.drop_all_tables() diff --git a/python/python/tests/test_db.py b/python/python/tests/test_db.py index a7cff5df..88bb33e8 100644 --- a/python/python/tests/test_db.py +++ b/python/python/tests/test_db.py @@ -499,6 +499,10 @@ def test_delete_table(tmp_db: lancedb.DBConnection): # if ignore_missing=True tmp_db.drop_table("does_not_exist", ignore_missing=True) + tmp_db.drop_all_tables() + + assert tmp_db.table_names() == [] + @pytest.mark.asyncio async def test_delete_table_async(tmp_db: lancedb.DBConnection): diff --git a/python/src/connection.rs b/python/src/connection.rs index 0edeebc6..975a756c 100644 --- a/python/src/connection.rs +++ b/python/src/connection.rs @@ -170,12 +170,11 @@ impl Connection { }) } - pub fn drop_db(self_: PyRef<'_, Self>) -> PyResult> { + pub fn drop_all_tables(self_: PyRef<'_, Self>) -> PyResult> { let inner = self_.get_inner()?.clone(); - future_into_py( - self_.py(), - async move { inner.drop_db().await.infer_error() }, - ) + future_into_py(self_.py(), async move { + inner.drop_all_tables().await.infer_error() + }) } } diff --git a/rust/lancedb/src/connection.rs b/rust/lancedb/src/connection.rs index 6f58a5f1..84e01208 100644 --- a/rust/lancedb/src/connection.rs +++ b/rust/lancedb/src/connection.rs @@ -418,6 +418,11 @@ impl Connection { self.uri.as_str() } + /// Get access to the underlying database + pub fn database(&self) -> &Arc { + &self.internal + } + /// Get the names of all tables in the database /// /// The names will be returned in lexicographical order (ascending) @@ -504,8 +509,14 @@ impl Connection { /// Drop the database /// /// This is the same as dropping all of the tables + #[deprecated(since = "0.15.1", note = "Use `drop_all_tables` instead")] pub async fn drop_db(&self) -> Result<()> { - self.internal.drop_db().await + self.internal.drop_all_tables().await + } + + /// Drops all tables in the database + pub async fn drop_all_tables(&self) -> Result<()> { + self.internal.drop_all_tables().await } /// Get the in-memory embedding registry. diff --git a/rust/lancedb/src/database.rs b/rust/lancedb/src/database.rs index 1f5e7cb8..c5e40544 100644 --- a/rust/lancedb/src/database.rs +++ b/rust/lancedb/src/database.rs @@ -128,6 +128,6 @@ pub trait Database: /// Drop a table in the database async fn drop_table(&self, name: &str) -> Result<()>; /// Drop all tables in the database - async fn drop_db(&self) -> Result<()>; + async fn drop_all_tables(&self) -> Result<()>; fn as_any(&self) -> &dyn std::any::Any; } diff --git a/rust/lancedb/src/database/listing.rs b/rust/lancedb/src/database/listing.rs index fe361252..ff38cbe0 100644 --- a/rust/lancedb/src/database/listing.rs +++ b/rust/lancedb/src/database/listing.rs @@ -529,7 +529,7 @@ impl Database for ListingDatabase { Ok(()) } - async fn drop_db(&self) -> Result<()> { + async fn drop_all_tables(&self) -> Result<()> { self.object_store .remove_dir_all(self.base_path.clone()) .await?; diff --git a/rust/lancedb/src/remote/db.rs b/rust/lancedb/src/remote/db.rs index 04b2436c..7c608c2f 100644 --- a/rust/lancedb/src/remote/db.rs +++ b/rust/lancedb/src/remote/db.rs @@ -237,7 +237,7 @@ impl Database for RemoteDatabase { Ok(()) } - async fn drop_db(&self) -> Result<()> { + async fn drop_all_tables(&self) -> Result<()> { Err(crate::Error::NotSupported { message: "Dropping databases is not supported in the remote API".to_string(), })