From 5d812b920fb628e50a42d3f6ea5d1dc8343e67e1 Mon Sep 17 00:00:00 2001 From: ikatyal2110 Date: Mon, 27 Jul 2026 14:42:17 +0000 Subject: [PATCH] Fix KeyError when passing an unrecognized string type to create_table or add_column Passing a valid SQLite type string that is not in COLUMN_TYPE_MAPPING, such as NUMERIC or ANY, raised KeyError instead of being used as-is. The fix falls back to the raw string value when the type is a string not present in the mapping, matching the documented behaviour: col_type accepts Python types or SQLite type strings. --- sqlite_utils/db.py | 8 ++++++-- tests/test_create.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index 713b11074..0f3d6f892 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -1480,7 +1480,9 @@ def sort_key(p): column_extras.append( f"REFERENCES {quote_identifier(fk.other_table)}({quote_identifier(cast(str, fk.other_column))}){_fk_actions_sql(fk)}" ) - column_type_str = COLUMN_TYPE_MAPPING[column_type] + column_type_str = COLUMN_TYPE_MAPPING.get(column_type) or ( + column_type if isinstance(column_type, str) else COLUMN_TYPE_MAPPING[column_type] + ) # Special case for strict tables to map FLOAT to REAL # Refs https://github.com/simonw/sqlite-utils/issues/644 if strict and column_type_str == "FLOAT": @@ -3121,7 +3123,9 @@ def add_column( sql = "ALTER TABLE {} ADD COLUMN {} {col_type}{not_null_default};".format( quote_identifier(self.name), quote_identifier(col_name), - col_type=fk_col_type or COLUMN_TYPE_MAPPING[col_type], + col_type=fk_col_type or COLUMN_TYPE_MAPPING.get(col_type) or ( + col_type if isinstance(col_type, str) else COLUMN_TYPE_MAPPING[col_type] + ), not_null_default=(" " + not_null_sql) if not_null_sql else "", ) self.db.execute(sql) diff --git a/tests/test_create.py b/tests/test_create.py index 40746bf91..d7e8209aa 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -110,6 +110,13 @@ def test_create_table_with_defaults(fresh_db): ) == table.schema +def test_create_table_with_unknown_string_type(fresh_db): + table = fresh_db.create_table("t", {"id": int, "value": "NUMERIC"}, pk="id") + assert table.schema == 'CREATE TABLE "t" (\n "id" INTEGER PRIMARY KEY,\n "value" NUMERIC\n)' + table2 = fresh_db.create_table("t2", {"id": int, "misc": "ANY"}, pk="id") + assert table2.schema == 'CREATE TABLE "t2" (\n "id" INTEGER PRIMARY KEY,\n "misc" ANY\n)' + + def test_create_table_with_bad_not_null(fresh_db): with pytest.raises(ValueError): fresh_db.create_table( @@ -375,6 +382,18 @@ def test_create_error_if_invalid_self_referential_foreign_keys(fresh_db): 'CREATE TABLE "dogs" (\n "name" TEXT\n, "float" FLOAT)', ), ("blob", "blob", None, 'CREATE TABLE "dogs" (\n "name" TEXT\n, "blob" BLOB)'), + ( + "score", + "NUMERIC", + None, + 'CREATE TABLE "dogs" (\n "name" TEXT\n, "score" NUMERIC)', + ), + ( + "misc", + "ANY", + None, + 'CREATE TABLE "dogs" (\n "name" TEXT\n, "misc" ANY)', + ), ( "default_str", None,