def get_date(self, instance):
user = instance.id
today = date.today()
if instance.date is not None:
return instance.date
# calculate last reported day if no specific date is set
max_absence_date = Absence.objects.filter(
user=user, date__lt=today).aggregate(date=Max('date'))
max_report_date = Report.objects.filter(
user=user, date__lt=today).aggregate(date=Max('date'))
last_reported_date = max(
max_absence_date['date'] or date.min,
max_report_date['date'] or date.min
)
instance.date = last_reported_date
return instance.date
python类min()的实例源码
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_timestamp(value, connection):
"""Cast a timestamp value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:5]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
else:
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
return datetime.strptime(' '.join(value), ' '.join(fmt))
def cast_timestamptz(value, connection):
"""Cast a timestamptz value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
value, tz = value[:-1], value[-1]
else:
if fmt.startswith('%Y-'):
tz = _re_timezone.match(value[1])
if tz:
value[1], tz = tz.groups()
else:
tz = '+0000'
else:
value, tz = value[:-1], value[-1]
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
if _has_timezone:
value.append(_timezone_as_offset(tz))
fmt.append('%z')
return datetime.strptime(' '.join(value), ' '.join(fmt))
return datetime.strptime(' '.join(value), ' '.join(fmt)).replace(
tzinfo=_get_timezone(tz))
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_timestamp(value, connection):
"""Cast a timestamp value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:5]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
else:
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
return datetime.strptime(' '.join(value), ' '.join(fmt))
def testTruncateRestart(self):
truncate = self.db.truncate
self.assertRaises(TypeError, truncate, 'test_table', restart='invalid')
query = self.db.query
self.createTable('test_table', 'n serial, t text')
for n in range(3):
query("insert into test_table (t) values ('test')")
q = "select count(n), min(n), max(n) from test_table"
r = query(q).getresult()[0]
self.assertEqual(r, (3, 1, 3))
truncate('test_table')
r = query(q).getresult()[0]
self.assertEqual(r, (0, None, None))
for n in range(3):
query("insert into test_table (t) values ('test')")
r = query(q).getresult()[0]
self.assertEqual(r, (3, 4, 6))
truncate('test_table', restart=True)
r = query(q).getresult()[0]
self.assertEqual(r, (0, None, None))
for n in range(3):
query("insert into test_table (t) values ('test')")
r = query(q).getresult()[0]
self.assertEqual(r, (3, 1, 3))
def testDate(self):
query = self.db.query
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = date(2016, 3, 14)
q = "select $1::date"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, date)
self.assertEqual(r, d)
q = "select '10000-08-01'::date, '0099-01-08 BC'::date"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], date)
self.assertIsInstance(r[1], date)
self.assertEqual(r[0], date.max)
self.assertEqual(r[1], date.min)
q = "select 'infinity'::date, '-infinity'::date"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], date)
self.assertIsInstance(r[1], date)
self.assertEqual(r[0], date.max)
self.assertEqual(r[1], date.min)
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_timestamp(value, connection):
"""Cast a timestamp value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:5]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
else:
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
return datetime.strptime(' '.join(value), ' '.join(fmt))
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_timestamp(value, connection):
"""Cast a timestamp value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:5]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
else:
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
return datetime.strptime(' '.join(value), ' '.join(fmt))
def cast_date(value, connection):
"""Cast a date value."""
# The output format depends on the server setting DateStyle. The default
# setting ISO and the setting for German are actually unambiguous. The
# order of days and months in the other two settings is however ambiguous,
# so at least here we need to consult the setting to properly parse values.
if value == '-infinity':
return date.min
if value == 'infinity':
return date.max
value = value.split()
if value[-1] == 'BC':
return date.min
value = value[0]
if len(value) > 10:
return date.max
fmt = connection.date_format()
return datetime.strptime(value, fmt).date()
def cast_timestamp(value, connection):
"""Cast a timestamp value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:5]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
else:
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
return datetime.strptime(' '.join(value), ' '.join(fmt))
def testTruncateRestart(self):
truncate = self.db.truncate
self.assertRaises(TypeError, truncate, 'test_table', restart='invalid')
query = self.db.query
self.createTable('test_table', 'n serial, t text')
for n in range(3):
query("insert into test_table (t) values ('test')")
q = "select count(n), min(n), max(n) from test_table"
r = query(q).getresult()[0]
self.assertEqual(r, (3, 1, 3))
truncate('test_table')
r = query(q).getresult()[0]
self.assertEqual(r, (0, None, None))
for n in range(3):
query("insert into test_table (t) values ('test')")
r = query(q).getresult()[0]
self.assertEqual(r, (3, 4, 6))
truncate('test_table', restart=True)
r = query(q).getresult()[0]
self.assertEqual(r, (0, None, None))
for n in range(3):
query("insert into test_table (t) values ('test')")
r = query(q).getresult()[0]
self.assertEqual(r, (3, 1, 3))
def testDate(self):
query = self.db.query
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = date(2016, 3, 14)
q = "select $1::date"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, date)
self.assertEqual(r, d)
q = "select '10000-08-01'::date, '0099-01-08 BC'::date"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], date)
self.assertIsInstance(r[1], date)
self.assertEqual(r[0], date.max)
self.assertEqual(r[1], date.min)
q = "select 'infinity'::date, '-infinity'::date"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], date)
self.assertIsInstance(r[1], date)
self.assertEqual(r[0], date.max)
self.assertEqual(r[1], date.min)
def testTimestamp(self):
query = self.db.query
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = datetime(2016, 3, 14)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, 535897)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
q = ("select '10000-08-01 AD'::timestamp,"
" '0099-01-08 BC'::timestamp")
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
q = "select 'infinity'::timestamp, '-infinity'::timestamp"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
def testTimestamptz(self):
query = self.db.query
timezones = dict(CET=1, EET=2, EST=-5, UTC=0)
for timezone in sorted(timezones):
tz = '%+03d00' % timezones[timezone]
try:
tzinfo = datetime.strptime(tz, '%z').tzinfo
except ValueError: # Python < 3.2
tzinfo = pg._get_timezone(tz)
self.db.set_parameter('timezone', timezone)
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = datetime(2016, 3, 14, tzinfo=tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, tzinfo=tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, 535897, tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
q = ("select '10000-08-01 AD'::timestamptz,"
" '0099-01-08 BC'::timestamptz")
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
q = "select 'infinity'::timestamptz, '-infinity'::timestamptz"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
def cast_timestamptz(value, connection):
"""Cast a timestamptz value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
value, tz = value[:-1], value[-1]
else:
if fmt.startswith('%Y-'):
tz = _re_timezone.match(value[1])
if tz:
value[1], tz = tz.groups()
else:
tz = '+0000'
else:
value, tz = value[:-1], value[-1]
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
if _has_timezone:
value.append(_timezone_as_offset(tz))
fmt.append('%z')
return datetime.strptime(' '.join(value), ' '.join(fmt))
return datetime.strptime(' '.join(value), ' '.join(fmt)).replace(
tzinfo=_get_timezone(tz))
def cast_timestamptz(value, connection):
"""Cast a timestamptz value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
value, tz = value[:-1], value[-1]
else:
if fmt.startswith('%Y-'):
tz = _re_timezone.match(value[1])
if tz:
value[1], tz = tz.groups()
else:
tz = '+0000'
else:
value, tz = value[:-1], value[-1]
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
if _has_timezone:
value.append(_timezone_as_offset(tz))
fmt.append('%z')
return datetime.strptime(' '.join(value), ' '.join(fmt))
return datetime.strptime(' '.join(value), ' '.join(fmt)).replace(
tzinfo=_get_timezone(tz))
test_pivot.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 25
收藏 0
点赞 0
评论 0
def test_pivot_integer_columns(self):
# caused by upstream bug in unstack
d = date.min
data = list(product(['foo', 'bar'], ['A', 'B', 'C'], ['x1', 'x2'],
[d + timedelta(i)
for i in range(20)], [1.0]))
df = DataFrame(data)
table = df.pivot_table(values=4, index=[0, 1, 3], columns=[2])
df2 = df.rename(columns=str)
table2 = df2.pivot_table(
values='4', index=['0', '1', '3'], columns=['2'])
tm.assert_frame_equal(table, table2, check_names=False)
def _make_combined_transactions(self):
"""
Combine all Transactions and ScheduledTransactions from
``self._data_cache`` into one ordered list of similar dicts, adding
dates to the monthly ScheduledTransactions as appropriate and excluding
ScheduledTransactions that have been converted to real Transactions.
Store the finished list back into ``self._data_cache``.
"""
unordered = []
# ScheduledTransaction ID to count of real trans for each
st_ids = defaultdict(int)
for t in self._data_cache['transactions']:
unordered.append(self._trans_dict(t))
if t.scheduled_trans_id is not None:
st_ids[t.scheduled_trans_id] += 1
for t in self._data_cache['st_date']:
if t.id not in st_ids:
unordered.append(self._trans_dict(t))
for t in self._data_cache['st_monthly']:
if t.id not in st_ids:
unordered.append(self._trans_dict(t))
ordered = []
for t in self._data_cache['st_per_period']:
d = self._trans_dict(t)
for _ in range(0, (t.num_per_period - st_ids[t.id])):
ordered.append(d)
for t in sorted(unordered, key=lambda k: k['date']):
ordered.append(t)
def sortkey(k):
d = k.get('date', None)
if d is None:
d = date.min
return d, k['amount']
return sorted(ordered, key=sortkey)
def __init__(self, env, retry_times=5, retry_interval=1):
self._env = env
self._retry_times = retry_times
self._retry_interval = retry_interval
self._cache = DataCache()
self._query_returns = {}
self._data_update_date = date.min
self.td_api = None
Environment.get_ins_dict = self.get_ins_dict
def cast_timestamptz(value, connection):
"""Cast a timestamptz value."""
if value == '-infinity':
return datetime.min
if value == 'infinity':
return datetime.max
value = value.split()
if value[-1] == 'BC':
return datetime.min
fmt = connection.date_format()
if fmt.endswith('-%Y') and len(value) > 2:
value = value[1:]
if len(value[3]) > 4:
return datetime.max
fmt = ['%d %b' if fmt.startswith('%d') else '%b %d',
'%H:%M:%S.%f' if len(value[2]) > 8 else '%H:%M:%S', '%Y']
value, tz = value[:-1], value[-1]
else:
if fmt.startswith('%Y-'):
tz = _re_timezone.match(value[1])
if tz:
value[1], tz = tz.groups()
else:
tz = '+0000'
else:
value, tz = value[:-1], value[-1]
if len(value[0]) > 10:
return datetime.max
fmt = [fmt, '%H:%M:%S.%f' if len(value[1]) > 8 else '%H:%M:%S']
if _has_timezone:
value.append(_timezone_as_offset(tz))
fmt.append('%z')
return datetime.strptime(' '.join(value), ' '.join(fmt))
return datetime.strptime(' '.join(value), ' '.join(fmt)).replace(
tzinfo=_get_timezone(tz))
def testTimestamp(self):
query = self.db.query
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = datetime(2016, 3, 14)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, 535897)
q = "select $1::timestamp"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
q = ("select '10000-08-01 AD'::timestamp,"
" '0099-01-08 BC'::timestamp")
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
q = "select 'infinity'::timestamp, '-infinity'::timestamp"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
def testTimestamptz(self):
query = self.db.query
timezones = dict(CET=1, EET=2, EST=-5, UTC=0)
for timezone in sorted(timezones):
tz = '%+03d00' % timezones[timezone]
try:
tzinfo = datetime.strptime(tz, '%z').tzinfo
except ValueError: # Python < 3.2
tzinfo = pg._get_timezone(tz)
self.db.set_parameter('timezone', timezone)
for datestyle in ('ISO', 'Postgres, MDY', 'Postgres, DMY',
'SQL, MDY', 'SQL, DMY', 'German'):
self.db.set_parameter('datestyle', datestyle)
d = datetime(2016, 3, 14, tzinfo=tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, tzinfo=tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
d = datetime(2016, 3, 14, 15, 9, 26, 535897, tzinfo)
q = "select $1::timestamptz"
r = query(q, (d,)).getresult()[0][0]
self.assertIsInstance(r, datetime)
self.assertEqual(r, d)
q = ("select '10000-08-01 AD'::timestamptz,"
" '0099-01-08 BC'::timestamptz")
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)
q = "select 'infinity'::timestamptz, '-infinity'::timestamptz"
r = query(q).getresult()[0]
self.assertIsInstance(r[0], datetime)
self.assertIsInstance(r[1], datetime)
self.assertEqual(r[0], datetime.max)
self.assertEqual(r[1], datetime.min)