mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-13 23:32:27 +00:00
feat(sdk): expose table overrides for remote tables
This commit is contained in:
@@ -494,6 +494,9 @@ class Table:
|
||||
async def set_lsm_write_spec(self, spec: LsmWriteSpec) -> None: ...
|
||||
async def unset_lsm_write_spec(self) -> None: ...
|
||||
async def get_lsm_write_spec(self) -> Optional[LsmWriteSpec]: ...
|
||||
async def get_table_overrides(self) -> str: ...
|
||||
async def update_table_overrides(self, overrides_json: str) -> str: ...
|
||||
async def reset_table_overrides(self) -> str: ...
|
||||
async def checkpoint_lsm(self) -> None: ...
|
||||
async def flush_lsm(self) -> None: ...
|
||||
async def compact_lsm(self) -> None: ...
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import inspect
|
||||
import json
|
||||
import deprecation
|
||||
import warnings
|
||||
from abc import ABC, abstractmethod
|
||||
@@ -4449,6 +4450,36 @@ class LanceTable(Table):
|
||||
[`AsyncTable.get_lsm_write_spec`][lancedb.AsyncTable.get_lsm_write_spec]."""
|
||||
return LOOP.run(self._table.get_lsm_write_spec())
|
||||
|
||||
def get_table_overrides(self) -> dict[str, Any]:
|
||||
"""Read Enterprise table overrides for this table.
|
||||
|
||||
Table overrides configure Enterprise-managed background behavior such as
|
||||
automatic compaction, cleanup, and reindex execution. This method is
|
||||
supported only on remote Enterprise tables.
|
||||
"""
|
||||
return LOOP.run(self._table.get_table_overrides())
|
||||
|
||||
def update_table_overrides(self, **overrides: Any) -> dict[str, Any]:
|
||||
"""Merge Enterprise table overrides into the current table overrides.
|
||||
|
||||
Only fields supplied in ``overrides`` are changed; unrelated existing
|
||||
overrides are preserved by the remote service update flow.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> table.update_table_overrides(
|
||||
... job_types={
|
||||
... "compaction": {"enabled": True},
|
||||
... "cleanup": {"enabled": False},
|
||||
... }
|
||||
... )
|
||||
"""
|
||||
return LOOP.run(self._table.update_table_overrides(**overrides))
|
||||
|
||||
def reset_table_overrides(self) -> dict[str, Any]:
|
||||
"""Clear Enterprise table overrides for this table."""
|
||||
return LOOP.run(self._table.reset_table_overrides())
|
||||
|
||||
def checkpoint_lsm(self) -> None:
|
||||
"""Synchronous version of
|
||||
[`AsyncTable.checkpoint_lsm`][lancedb.AsyncTable.checkpoint_lsm]."""
|
||||
@@ -5188,6 +5219,37 @@ class AsyncTable:
|
||||
"""
|
||||
return await self._inner.get_lsm_write_spec()
|
||||
|
||||
async def get_table_overrides(self) -> dict[str, Any]:
|
||||
"""Read Enterprise table overrides for this table.
|
||||
|
||||
Table overrides configure Enterprise-managed background behavior such as
|
||||
automatic compaction, cleanup, and reindex execution. This method is
|
||||
supported only on remote Enterprise tables.
|
||||
"""
|
||||
return json.loads(await self._inner.get_table_overrides())
|
||||
|
||||
async def update_table_overrides(self, **overrides: Any) -> dict[str, Any]:
|
||||
"""Merge Enterprise table overrides into the current table overrides.
|
||||
|
||||
Only fields supplied in ``overrides`` are changed; unrelated existing
|
||||
overrides are preserved by the remote service update flow.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> await table.update_table_overrides(
|
||||
... job_types={
|
||||
... "compaction": {"enabled": True},
|
||||
... "cleanup": {"enabled": False},
|
||||
... }
|
||||
... )
|
||||
"""
|
||||
encoded = json.dumps(overrides)
|
||||
return json.loads(await self._inner.update_table_overrides(encoded))
|
||||
|
||||
async def reset_table_overrides(self) -> dict[str, Any]:
|
||||
"""Clear Enterprise table overrides for this table."""
|
||||
return json.loads(await self._inner.reset_table_overrides())
|
||||
|
||||
async def checkpoint_lsm(self) -> None:
|
||||
"""Converge this table's LSM write path into its base table.
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import ctypes
|
||||
import gc
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
@@ -1640,6 +1641,66 @@ def test_create_index_method(mock_create_index, mem_db: DBConnection):
|
||||
)
|
||||
|
||||
|
||||
@patch("lancedb.table.AsyncTable.get_table_overrides")
|
||||
def test_get_table_overrides_method(mock_get_table_overrides, mem_db: DBConnection):
|
||||
expected = {"job_types": {"cleanup": {"enabled": False}}}
|
||||
mock_get_table_overrides.return_value = expected
|
||||
table = mem_db.create_table("test", data=[{"id": 1}])
|
||||
|
||||
assert table.get_table_overrides() == expected
|
||||
mock_get_table_overrides.assert_called_once_with()
|
||||
|
||||
|
||||
@patch("lancedb.table.AsyncTable.update_table_overrides")
|
||||
def test_update_table_overrides_method(
|
||||
mock_update_table_overrides, mem_db: DBConnection
|
||||
):
|
||||
overrides = {
|
||||
"job_types": {
|
||||
"cleanup": {"enabled": False},
|
||||
"index": {
|
||||
"scalar": {
|
||||
"reindex": {
|
||||
"row_threshold": 1000,
|
||||
"ttl_millis": 300000,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
mock_update_table_overrides.return_value = overrides
|
||||
table = mem_db.create_table("test", data=[{"id": 1}])
|
||||
|
||||
assert table.update_table_overrides(**overrides) == overrides
|
||||
mock_update_table_overrides.assert_called_once_with(**overrides)
|
||||
|
||||
|
||||
@patch("lancedb.table.AsyncTable.reset_table_overrides")
|
||||
def test_reset_table_overrides_method(mock_reset_table_overrides, mem_db: DBConnection):
|
||||
expected = {}
|
||||
mock_reset_table_overrides.return_value = expected
|
||||
table = mem_db.create_table("test", data=[{"id": 1}])
|
||||
|
||||
assert table.reset_table_overrides() == expected
|
||||
mock_reset_table_overrides.assert_called_once_with()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_update_table_overrides_encodes_json():
|
||||
class MockInner:
|
||||
async def update_table_overrides(self, encoded_overrides):
|
||||
assert json.loads(encoded_overrides) == {
|
||||
"job_types": {"cleanup": {"enabled": False}}
|
||||
}
|
||||
return json.dumps({"job_types": {"cleanup": {"enabled": False}}})
|
||||
|
||||
table = lancedb.table.AsyncTable(MockInner())
|
||||
|
||||
assert await table.update_table_overrides(
|
||||
job_types={"cleanup": {"enabled": False}}
|
||||
) == {"job_types": {"cleanup": {"enabled": False}}}
|
||||
|
||||
|
||||
@patch("lancedb.table.AsyncTable.create_index")
|
||||
def test_create_index_name_and_train_parameters(
|
||||
mock_create_index, mem_db: DBConnection
|
||||
|
||||
@@ -1603,6 +1603,45 @@ impl Table {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_table_overrides(self_: PyRef<'_, Self>) -> PyResult<Bound<'_, PyAny>> {
|
||||
let inner = self_.inner_ref()?.clone();
|
||||
future_into_py(self_.py(), async move {
|
||||
let overrides = inner.get_table_overrides().await.infer_error()?;
|
||||
serde_json::to_string(&overrides).map_err(|err| {
|
||||
PyRuntimeError::new_err(format!("Failed to serialize table overrides: {err}"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update_table_overrides<'a>(
|
||||
self_: PyRef<'a, Self>,
|
||||
overrides_json: String,
|
||||
) -> PyResult<Bound<'a, PyAny>> {
|
||||
let inner = self_.inner_ref()?.clone();
|
||||
future_into_py(self_.py(), async move {
|
||||
let overrides = serde_json::from_str(&overrides_json).map_err(|err| {
|
||||
PyValueError::new_err(format!("Invalid table overrides JSON: {err}"))
|
||||
})?;
|
||||
let overrides = inner
|
||||
.update_table_overrides(overrides)
|
||||
.await
|
||||
.infer_error()?;
|
||||
serde_json::to_string(&overrides).map_err(|err| {
|
||||
PyRuntimeError::new_err(format!("Failed to serialize table overrides: {err}"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reset_table_overrides(self_: PyRef<'_, Self>) -> PyResult<Bound<'_, PyAny>> {
|
||||
let inner = self_.inner_ref()?.clone();
|
||||
future_into_py(self_.py(), async move {
|
||||
let overrides = inner.reset_table_overrides().await.infer_error()?;
|
||||
serde_json::to_string(&overrides).map_err(|err| {
|
||||
PyRuntimeError::new_err(format!("Failed to serialize table overrides: {err}"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Converge the table's LSM write path into its base table.
|
||||
///
|
||||
/// Best-effort: with writes flowing, new rows may land after the last
|
||||
|
||||
Reference in New Issue
Block a user