Resolve problem displaying intervals and timestamps. Fixes #1352

1) No handling for INTERVAL type datetime.
For example: executing query
SELECT INTERVAL '15 minutes';
throws json serialization error, because it returns time in timedelta format which is not handled.

Added support to handle timedelta datetime format in DataTypeJSONEncoder class

2) When we try to get BC dates from database raises ValueError: year is out of range
For eg:
SELECT TIMESTAMP '0044-03-15 10:00:00 BC',
It is because pyscopg2 doesn't handle BC datetime format.

So we have defined our method which type cast the datetime value to string in pyscopg2 overriding default behaviour.

Reference:
http://initd.org/psycopg/docs/advanced.html#type-casting-from-sql-to-python
ccf3693be6/pgcli/pgexecute.py
This commit is contained in:
Surinder Kumar 2016-06-14 17:09:47 +01:00 committed by Dave Page
parent e881695050
commit 5dbbd8e638
2 changed files with 22 additions and 0 deletions

View File

@ -21,6 +21,8 @@ class DataTypeJSONEncoder(json.JSONEncoder):
if isinstance(obj, datetime.datetime) \
or hasattr(obj, 'isoformat'):
return obj.isoformat()
elif isinstance(obj, datetime.timedelta):
return (datetime.datetime.min + obj).time().isoformat()
if isinstance(obj, decimal.Decimal):
return float(obj)

View File

@ -38,6 +38,25 @@ _ = gettext
ASYNC_WAIT_TIMEOUT = 0.01 # in seconds or 10 milliseconds
def register_date_typecasters(connection):
"""
Casts date and timestamp values to string, resolves issues
with out of range dates (e.g. BC) which psycopg2 can't handle
"""
def cast_date(value, cursor):
return value
cursor = connection.cursor()
cursor.execute('SELECT NULL::date')
date_oid = cursor.description[0][1]
cursor.execute('SELECT NULL::timestamp')
timestamp_oid = cursor.description[0][1]
cursor.execute('SELECT NULL::timestamptz')
timestamptz_oid = cursor.description[0][1]
oids = (date_oid, timestamp_oid, timestamptz_oid)
new_type = psycopg2.extensions.new_type(oids, 'DATE', cast_date)
psycopg2.extensions.register_type(new_type)
class Connection(BaseConnection):
"""
class Connection(object)
@ -244,6 +263,7 @@ Failed to connect to the database server(#{server_id}) for connection ({conn_id}
# By default asynchronous connection runs in autocommit mode.
if self.async == 0:
self.conn.autocommit = True
register_date_typecasters(self.conn)
status, res = self.execute_scalar("""
SET DateStyle=ISO;