Skip to content
This repository was archived by the owner on Sep 23, 2024. It is now read-only.

Commit 280aaf0

Browse files
authored
Handle dates with year > 9999 (#122)
1 parent b1ba14d commit 280aaf0

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

tap_postgres/sync_strategies/logical_replication.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
UPDATE_BOOKMARK_PERIOD = 10000
2323
FALLBACK_DATETIME = '9999-12-31T23:59:59.999+00:00'
24+
FALLBACK_DATE = '9999-12-31T00:00:00+00:00'
2425

2526

2627
class ReplicationSlotNotFoundError(Exception):
@@ -286,7 +287,15 @@ def selected_value_to_singer_value_impl(elem, og_sql_datatype, conn_info):
286287
if isinstance(elem, datetime.date):
287288
# logical replication gives us dates as strings UNLESS they from an array
288289
return elem.isoformat() + 'T00:00:00+00:00'
289-
return parse(elem).isoformat() + "+00:00"
290+
try:
291+
return parse(elem).isoformat() + "+00:00"
292+
except ValueError as e:
293+
match = re.match(r'year (\d+) is out of range', str(e))
294+
if match and int(match.group(1)) > 9999:
295+
LOGGER.warning('datetimes cannot handle years past 9999, returning %s for %s',
296+
FALLBACK_DATE, elem)
297+
return FALLBACK_DATE
298+
raise
290299
if sql_datatype == 'time with time zone':
291300
# time with time zone values will be converted to UTC and time zone dropped
292301
# Replace hour=24 with hour=0

tests/test_logical_replication.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ def test_selected_value_to_singer_value_impl_with_timestamp_tz_value_as_datetime
429429

430430
self.assertEqual('9999-12-31T23:59:59.999+00:00', output)
431431

432+
def test_selected_value_to_singer_value_impl_with_date_value_as_string_expect_iso_format(self):
433+
output = logical_replication.selected_value_to_singer_value_impl('2021-09-07', 'date', None)
434+
435+
self.assertEqual('2021-09-07T00:00:00+00:00', output)
436+
437+
def test_selected_value_to_singer_value_impl_with_date_value_as_string_out_of_range(self):
438+
"""
439+
Test selected_value_to_singer_value_impl with date as string where year
440+
is > 9999 (which is valid in postgres) should fallback to max date
441+
allowed
442+
"""
443+
output = logical_replication.selected_value_to_singer_value_impl('10000-09-01', 'date', None)
444+
445+
self.assertEqual('9999-12-31T00:00:00+00:00', output)
446+
432447
def test_row_to_singer_message(self):
433448
stream = {
434449
'stream': 'my_stream',

0 commit comments

Comments
 (0)