diff --git a/singer_sdk/typing.py b/singer_sdk/typing.py index f2766944c..1e70f6201 100644 --- a/singer_sdk/typing.py +++ b/singer_sdk/typing.py @@ -825,7 +825,9 @@ def _jsonschema_type_check(jsonschema_type: dict, type_check: tuple[str]) -> boo if jsonschema_type.get("type") in type_check: # noqa: PLR5501 return True - if any(t in type_check for t in jsonschema_type.get("anyOf", ())): + if any( + _jsonschema_type_check(t, type_check) for t in jsonschema_type.get("anyOf", ()) + ): return True return False diff --git a/tests/core/test_typing.py b/tests/core/test_typing.py index 854669e5b..b2cf9c691 100644 --- a/tests/core/test_typing.py +++ b/tests/core/test_typing.py @@ -4,7 +4,9 @@ import datetime import logging -import typing as t + +import pytest +import sqlalchemy from singer_sdk.helpers._typing import ( TypeConformanceLevel, @@ -17,11 +19,9 @@ PropertiesList, Property, StringType, + to_sql_type, ) -if t.TYPE_CHECKING: - import pytest - logger = logging.getLogger("log") @@ -292,3 +292,29 @@ def test_conform_primitives(): assert _conform_primitive_property(None, {"type": "boolean"}) is None assert _conform_primitive_property(0, {"type": "boolean"}) is False assert _conform_primitive_property(1, {"type": "boolean"}) is True + + +@pytest.mark.parametrize( + "jsonschema_type,expected", + [ + ({"type": ["string", "null"]}, sqlalchemy.types.VARCHAR), + ({"type": ["integer", "null"]}, sqlalchemy.types.INTEGER), + ({"type": ["number", "null"]}, sqlalchemy.types.DECIMAL), + ({"type": ["boolean", "null"]}, sqlalchemy.types.BOOLEAN), + ({"type": "object", "properties": {}}, sqlalchemy.types.VARCHAR), + ({"type": "array"}, sqlalchemy.types.VARCHAR), + ({"format": "date", "type": ["string", "null"]}, sqlalchemy.types.DATE), + ({"format": "time", "type": ["string", "null"]}, sqlalchemy.types.TIME), + ( + {"format": "date-time", "type": ["string", "null"]}, + sqlalchemy.types.DATETIME, + ), + ( + {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]}, + sqlalchemy.types.DATETIME, + ), + ({"anyOf": [{"type": "integer"}, {"type": "null"}]}, sqlalchemy.types.INTEGER), + ], +) +def test_to_sql_type(jsonschema_type, expected): + assert isinstance(to_sql_type(jsonschema_type), expected)