From f260d3bf127c00a475e1e77821d0a2db9f14534b Mon Sep 17 00:00:00 2001 From: devteamaegis Date: Tue, 9 Jun 2026 18:57:02 -0400 Subject: [PATCH] fix(util): convert numpy scalars in value_to_sql (#3522) ## What's broken `Table.update(values={...})` raises `NotImplementedError: SQL conversion is not implemented for this type` when a value is a numpy scalar such as `np.int64`, `np.int32`, `np.float32`, or `np.bool_`. These arise naturally from indexing an ndarray or a pandas int/bool column. `np.float64` happens to work (it subclasses `float`), which makes the failure inconsistent and surprising. ```python df = pd.DataFrame({"id": np.array([10, 20], dtype="int32")}) t.update(where="id = 1", values={"id": df["id"].iloc[0]}) # np.int32 # -> NotImplementedError: SQL conversion is not implemented for this type ``` ## Why it happens `value_to_sql` is a `singledispatch` with handlers only for native Python types and `np.ndarray`; numpy `integer`/`floating`/`bool_` scalars aren't Python subclasses, so they fall through to the `NotImplementedError` base. ## Fix Register handlers for `np.bool_`, `np.integer`, and `np.floating` that delegate to the existing native handlers. ## Test `value_to_sql` on `np.int32/int64/float32/float64/bool_` all convert; `np.int32` raised before. Co-authored-by: Ishaan Samantray --- python/python/lancedb/util.py | 15 +++++++++++++++ python/python/tests/test_util.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/python/python/lancedb/util.py b/python/python/lancedb/util.py index b8e519933..e9d01407b 100644 --- a/python/python/lancedb/util.py +++ b/python/python/lancedb/util.py @@ -385,6 +385,21 @@ def _(value: np.ndarray): return value_to_sql(value.tolist()) +@value_to_sql.register(np.bool_) +def _(value: np.bool_): + return value_to_sql(bool(value)) + + +@value_to_sql.register(np.integer) +def _(value: np.integer): + return value_to_sql(int(value)) + + +@value_to_sql.register(np.floating) +def _(value: np.floating): + return value_to_sql(float(value)) + + def deprecated(func): """This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emitted diff --git a/python/python/tests/test_util.py b/python/python/tests/test_util.py index b5ab159b7..f3051d45a 100644 --- a/python/python/tests/test_util.py +++ b/python/python/tests/test_util.py @@ -149,6 +149,21 @@ def test_value_to_sql_dict(): assert value_to_sql({}) == "named_struct()" +def test_value_to_sql_numpy_scalars(): + # numpy scalars (e.g. pulled from an ndarray or a pandas column) must + # convert the same way as their native Python counterparts. np.float64 + # already worked by virtue of subclassing float, but the integer / bool + # / float32 scalars previously raised NotImplementedError. + import numpy as np + + assert value_to_sql(np.int32(5)) == "5" + assert value_to_sql(np.int64(5)) == "5" + assert value_to_sql(np.float32(1.5)) == "1.5" + assert value_to_sql(np.float64(1.5)) == "1.5" + assert value_to_sql(np.bool_(True)) == "TRUE" + assert value_to_sql(np.bool_(False)) == "FALSE" + + def test_append_vector_columns(): registry = EmbeddingFunctionRegistry.get_instance() registry.register("test")(MockTextEmbeddingFunction)