From 3d90742d0d49f7f981c8b4254445b2c1517df0d0 Mon Sep 17 00:00:00 2001 From: Tanbir Date: Wed, 23 Sep 2026 17:25:18 +0200 Subject: [PATCH] Convert numpy integer and float scalars to Python numbers on insert, closes #876 --- sqlite_utils/db.py | 3 +++ tests/test_create.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index c011d9bb0..c46c61c9d 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -5501,6 +5501,9 @@ def drop(self, ignore: bool = False) -> None: def jsonify_if_needed(value: object) -> object: if isinstance(value, decimal.Decimal): return float(value) + if np is not None and isinstance(value, (np.integer, np.floating)): + # sqlite3 would otherwise store the raw buffer as a BLOB + return cast(Any, value).item() if isinstance(value, (dict, list, tuple)): return json.dumps(value, default=repr, ensure_ascii=False) elif isinstance(value, (datetime.time, datetime.date, datetime.datetime)): diff --git a/tests/test_create.py b/tests/test_create.py index b738df952..42448ebc9 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -1739,3 +1739,42 @@ def test_chained_create_sets_pks(fresh_db): {"id": int, "name": str, "color": str} ) assert table.pks == ["id"] + + +def test_insert_raw_numpy_scalars(fresh_db): + # https://github.com/simonw/sqlite-utils/issues/876 + np = pytest.importorskip("numpy") + row = { + "int8": np.int8(-8), + "int64": np.int64(5), + "uint64": np.uint64(64), + "float16": np.float16(16.5), + "float32": np.float32(32.5), + "float64": np.float64(64.5), + } + table = fresh_db.table("t") + table.insert(row) + table.insert_all([row]) + assert table.columns_dict == { + "int8": int, + "int64": int, + "uint64": int, + "float16": float, + "float32": float, + "float64": float, + } + expected = { + "int8": -8, + "int64": 5, + "uint64": 64, + "float16": 16.5, + "float32": 32.5, + "float64": 64.5, + } + assert list(table.rows) == [expected, expected] + assert fresh_db.execute( + "select typeof(int64), typeof(float32) from t" + ).fetchall() == [ + ("integer", "real"), + ("integer", "real"), + ]