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

Commit

Permalink
Handle dates with year > 9999 (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
deanmorin authored Sep 15, 2021
1 parent b1ba14d commit 280aaf0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
11 changes: 10 additions & 1 deletion tap_postgres/sync_strategies/logical_replication.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

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


class ReplicationSlotNotFoundError(Exception):
Expand Down Expand Up @@ -286,7 +287,15 @@ def selected_value_to_singer_value_impl(elem, og_sql_datatype, conn_info):
if isinstance(elem, datetime.date):
# logical replication gives us dates as strings UNLESS they from an array
return elem.isoformat() + 'T00:00:00+00:00'
return parse(elem).isoformat() + "+00:00"
try:
return parse(elem).isoformat() + "+00:00"
except ValueError as e:
match = re.match(r'year (\d+) is out of range', str(e))
if match and int(match.group(1)) > 9999:
LOGGER.warning('datetimes cannot handle years past 9999, returning %s for %s',
FALLBACK_DATE, elem)
return FALLBACK_DATE
raise
if sql_datatype == 'time with time zone':
# time with time zone values will be converted to UTC and time zone dropped
# Replace hour=24 with hour=0
Expand Down
15 changes: 15 additions & 0 deletions tests/test_logical_replication.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,21 @@ def test_selected_value_to_singer_value_impl_with_timestamp_tz_value_as_datetime

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

def test_selected_value_to_singer_value_impl_with_date_value_as_string_expect_iso_format(self):
output = logical_replication.selected_value_to_singer_value_impl('2021-09-07', 'date', None)

self.assertEqual('2021-09-07T00:00:00+00:00', output)

def test_selected_value_to_singer_value_impl_with_date_value_as_string_out_of_range(self):
"""
Test selected_value_to_singer_value_impl with date as string where year
is > 9999 (which is valid in postgres) should fallback to max date
allowed
"""
output = logical_replication.selected_value_to_singer_value_impl('10000-09-01', 'date', None)

self.assertEqual('9999-12-31T00:00:00+00:00', output)

def test_row_to_singer_message(self):
stream = {
'stream': 'my_stream',
Expand Down

0 comments on commit 280aaf0

Please sign in to comment.