Skip to content

Commit 894f376

Browse files
authored
Support for fractional seconds when binding time and datetime data types (#40)
1 parent fa5ceca commit 894f376

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

sqlalchemy_aurora_data_api/__init__.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ def bind_expression(self, value):
4242
class _ADA_DATETIME_MIXIN:
4343
iso_ts_re = re.compile(r"\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d+")
4444

45+
@staticmethod
46+
def ms(value):
47+
# Three digit fractional second component, truncated and zero padded. This is what the data api requires.
48+
return str(value.microsecond).zfill(6)[:-3]
49+
4550
def bind_processor(self, dialect):
4651
def process(value):
4752
return value.isoformat() if isinstance(value, self.py_type) else value
@@ -53,7 +58,8 @@ def bind_expression(self, value):
5358
def result_processor(self, dialect, coltype):
5459
def process(value):
5560
# When the microsecond component ends in zeros, they are omitted from the return value,
56-
# and datetime.datetime.fromisoformat can't parse the result (example: '2019-10-31 09:37:17.31869'). Pad it.
61+
# and datetime.datetime.fromisoformat can't parse the result (example: '2019-10-31 09:37:17.31869
62+
# '). Pad it.
5763
if isinstance(value, str) and self.iso_ts_re.match(value):
5864
value = self.iso_ts_re.sub(lambda match: match.group(0).ljust(26, "0"), value)
5965
if isinstance(value, str):
@@ -87,7 +93,7 @@ class _ADA_TIME(_ADA_DATETIME_MIXIN, TIME):
8793

8894
def bind_processor(self, dialect):
8995
def process(value):
90-
return value.strftime("%H:%M:%S") if isinstance(value, self.py_type) else value
96+
return value.strftime("%H:%M:%S.") + self.ms(value) if isinstance(value, self.py_type) else value
9197
return process
9298

9399

@@ -97,7 +103,7 @@ class _ADA_TIMESTAMP(_ADA_DATETIME_MIXIN, TIMESTAMP):
97103

98104
def bind_processor(self, dialect):
99105
def process(value):
100-
return value.strftime("%Y-%m-%d %H:%M:%S") if isinstance(value, self.py_type) else value
106+
return value.strftime("%Y-%m-%d %H:%M:%S.") + self.ms(value) if isinstance(value, self.py_type) else value
101107
return process
102108

103109

test/test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def test_orm(self):
174174
blob = b"0123456789ABCDEF" * 1024
175175
friends = ["Scarlett O'Hara", 'Ada "Hacker" Lovelace']
176176
Base.metadata.create_all(self.engine)
177-
added = datetime.datetime.now()
177+
added = datetime.datetime.now().replace(microsecond=123456)
178178
ed_user = User(name='ed', fullname='Ed Jones', nickname='edsnickname', doc=doc, doc2=doc, uuid=str(uuid),
179179
flag=True, birthday=datetime.datetime.fromtimestamp(0), added=added, floated=1.2, nybbled=blob,
180180
friends=friends, num_friends=500, num_laptops=9000, first_date=added, note='note',
@@ -195,7 +195,7 @@ def test_orm(self):
195195
self.assertEqual(u.flag, True)
196196
self.assertEqual(u.nonesuch, None)
197197
self.assertEqual(u.birthday, datetime.date.fromtimestamp(0))
198-
self.assertEqual(u.added, added.replace(microsecond=0))
198+
self.assertEqual(u.added, added.replace(microsecond=123000))
199199
self.assertEqual(u.floated, 1.2)
200200
self.assertEqual(u.nybbled, blob)
201201
self.assertEqual(u.friends, friends)

0 commit comments

Comments
 (0)