Skip to content

Commit b416c11

Browse files
committed
Types: Accept marshalling datetime.date values on DateTime fields
The test suite of `meltano-tap-cratedb`, derived from the corresponding PostgreSQL adapter, will supply `dt.date` objects. Without this patch, those will otherwise fail on this routine.
1 parent fb4c7be commit b416c11

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- Fixed SQL rendering of special DDL table options in `CrateDDLCompiler`.
1515
Before, configuring `crate_"translog.durability"` was not possible.
1616
- Unlocked supporting timezone-aware `DateTime` fields
17+
- Added support for marshalling Python `datetime.date` values on `sa.DateTime` fields
1718

1819
## 2024/06/13 0.37.0
1920
- Added support for CrateDB's [FLOAT_VECTOR] data type and its accompanying

src/sqlalchemy_cratedb/dialect.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ class DateTime(sqltypes.DateTime):
115115

116116
def bind_processor(self, dialect):
117117
def process(value):
118-
if value is not None:
119-
assert isinstance(value, datetime)
118+
if isinstance(value, (datetime, date)):
120119
return value.strftime('%Y-%m-%dT%H:%M:%S.%f%z')
121120
return value
122121
return process

tests/datetime_test.py

+30
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,33 @@ def test_datetime_tz(session):
184184
assert result["datetime_tz"].tzname() is None
185185
assert result["datetime_tz"].timetz() == OUTPUT_TIMETZ_TZ
186186
assert result["datetime_tz"].tzinfo is None
187+
188+
189+
@pytest.mark.skipif(SA_VERSION < SA_1_4, reason="Test case not supported on SQLAlchemy 1.3")
190+
def test_datetime_date(session):
191+
"""
192+
Validate assigning a `date` object to a `datetime` column works.
193+
194+
It is needed by meltano-tap-cratedb.
195+
196+
The test suite of `meltano-tap-cratedb`, derived from the corresponding
197+
PostgreSQL adapter, will supply `dt.date` objects. Without this improvement,
198+
those will otherwise fail.
199+
"""
200+
201+
# Insert record.
202+
foo_item = FooBar(
203+
name="foo",
204+
datetime_notz=dt.date(2009, 5, 13),
205+
datetime_tz=dt.date(2009, 5, 13),
206+
)
207+
session.add(foo_item)
208+
session.commit()
209+
session.execute(sa.text("REFRESH TABLE foobar"))
210+
211+
# Query record.
212+
result = session.execute(sa.select(FooBar.name, FooBar.date, FooBar.datetime_notz, FooBar.datetime_tz)).mappings().first()
213+
214+
# Compare outcome.
215+
assert result["datetime_notz"] == dt.datetime(2009, 5, 13, 0, 0, 0)
216+
assert result["datetime_tz"] == dt.datetime(2009, 5, 13, 0, 0, 0)

0 commit comments

Comments
 (0)