Skip to content

Commit 04765c4

Browse files
sfc-gh-stakedaankit-bhatnagar167
authored andcommitted
SNOW-90646: Make TIMESTAMP_TZ result pickle-able.
1 parent da81628 commit 04765c4

File tree

3 files changed

+29
-31
lines changed

3 files changed

+29
-31
lines changed

converter.py

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import binascii
77
import decimal
88
import time
9-
from datetime import datetime, timedelta, tzinfo, date
9+
from datetime import datetime, timedelta, date
1010
from logging import getLogger
1111

1212
import pytz
@@ -34,9 +34,6 @@
3434
ZERO_EPOCH = datetime.utcfromtimestamp(0)
3535
ZERO_FILL = u'000000000'
3636

37-
# Tzinfo class cache
38-
_TZINFO_CLASS_CACHE = {}
39-
4037
logger = getLogger(__name__)
4138

4239
PYTHON_TO_SNOWFLAKE_TYPE = {
@@ -132,31 +129,7 @@ def _generate_tzinfo_from_tzoffset(tzoffset_minutes):
132129
"""
133130
Generates tzinfo object from tzoffset.
134131
"""
135-
try:
136-
return _TZINFO_CLASS_CACHE[tzoffset_minutes]
137-
except KeyError:
138-
pass
139-
sign = u'P' if tzoffset_minutes >= 0 else u'N'
140-
abs_tzoffset_minutes = abs(tzoffset_minutes)
141-
hour, minute = divmod(abs_tzoffset_minutes, 60)
142-
name = u'GMT{sign:s}{hour:02d}{minute:02d}'.format(
143-
sign=sign,
144-
hour=hour,
145-
minute=minute)
146-
tzinfo_class_type = type(
147-
str(name), # str() for both Python 2 and 3
148-
(tzinfo,),
149-
dict(
150-
utcoffset=lambda self0, dt, is_dst=False: timedelta(
151-
minutes=tzoffset_minutes),
152-
tzname=lambda self0, dt: name,
153-
dst=lambda self0, dt: ZERO_TIMEDELTA,
154-
__repr__=lambda _: name
155-
)
156-
)
157-
tzinfo_cls = tzinfo_class_type()
158-
_TZINFO_CLASS_CACHE[tzoffset_minutes] = tzinfo_cls
159-
return tzinfo_cls
132+
return pytz.FixedOffset(tzoffset_minutes)
160133

161134

162135
class SnowflakeConverter(object):

test/test_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
def _compose_tz(dt, tzinfo):
2020
ret = ZERO_EPOCH + timedelta(seconds=float(dt))
21-
ret += tzinfo.utcoffset(ret, is_dst=False)
21+
ret += tzinfo.utcoffset(ret)
2222
return ret.replace(tzinfo=tzinfo)
2323

2424

@@ -28,7 +28,7 @@ def _compose_ntz(dt):
2828

2929
def _compose_ltz(dt, tz):
3030
ret = ZERO_EPOCH + timedelta(seconds=float(dt))
31-
return pytz.utc.localize(ret, is_dst=False).astimezone(
31+
return pytz.utc.localize(ret).astimezone(
3232
pytz.timezone(tz))
3333

3434

test/test_pickle_timestamp_tz.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (c) 2012-2019 Snowflake Computing Inc. All right reserved.
5+
#
6+
import os
7+
import pickle
8+
9+
10+
def test_pickle_timestamp_tz(tmpdir, conn_cnx):
11+
"""
12+
Ensure the timestamp_tz result is pickle-able.
13+
"""
14+
tmp_dir = str(tmpdir.mkdir('pickles'))
15+
output = os.path.join(tmp_dir, 'tz.pickle')
16+
expected_tz = None
17+
with conn_cnx() as con:
18+
for rec in con.cursor().execute("select '2019-08-11 01:02:03.123 -03:00'::TIMESTAMP_TZ"):
19+
expected_tz = rec[0]
20+
with open(output, 'wb') as f:
21+
pickle.dump(expected_tz, f)
22+
23+
with open(output, 'rb') as f:
24+
read_tz = pickle.load(f)
25+
assert expected_tz == read_tz

0 commit comments

Comments
 (0)