diff --git a/pyproject.toml b/pyproject.toml index 7f5fa1f..e8962b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "shaped-target-clickhouse" -version = "0.2.3" +version = "0.2.4" description = "`target-clickhouse` is a Singer target for clickhouse, built with the Meltano Singer SDK." readme = "README.md" authors = ["Ben Theunissen"] diff --git a/target_clickhouse/connectors.py b/target_clickhouse/connectors.py index 4655af5..11d5bd4 100644 --- a/target_clickhouse/connectors.py +++ b/target_clickhouse/connectors.py @@ -100,6 +100,14 @@ def to_sql_type(self, jsonschema_type: dict) -> sqlalchemy.types.TypeEngine: sql_type = typing.cast( sqlalchemy.types.TypeEngine, clickhouse_sqlalchemy_types.Int64(), ) + # All date and time types should be flagged as Nullable to allow for NULL value. + elif type(sql_type) in [ + sqlalchemy.types.DATE, + sqlalchemy.types.TIMESTAMP, + sqlalchemy.types.TIME, + sqlalchemy.types.DATETIME, + ]: + sql_type = clickhouse_sqlalchemy_types.Nullable(sql_type) return sql_type diff --git a/tests/target_test_cases.py b/tests/target_test_cases.py index 167f367..485dd6e 100644 --- a/tests/target_test_cases.py +++ b/tests/target_test_cases.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) class TestDateTypeTargetClickhouse(TargetClickhouseFileTestTemplate): - """Test date type can be ingested into Clickhouse.""" + """Test date type, and null date type can be ingested into Clickhouse.""" name = "date_type" @@ -30,6 +30,11 @@ def validate(self) -> None: record for record in result if record[0] == record_id_2 ])) assert record_2[1] == datetime.date(2024, 3, 16) + record_id_3 = 3 + record_3 = next(iter([ + record for record in result if record[0] == record_id_3 + ])) + assert record_3[1] is None custom_target_test_suite = TestSuite( kind="target",