Re: Interval Type Mapping
Francois Girault <francois.girault-ZQ1FT/[email protected]> Thu, 8 Jan 2004 11:16:15 +0100
| Newsgroups | gmane.comp.python.db.pypgsql.user |
|---|---|
| Organization | Clarisys Informatique |
| Message-ID | <[email protected]> |
Well... I did it ! See attached patch. On Thu, 18 Dec 2003 18:29:10 +0100 Francois Girault wrote: > Hi all, > > I'm using interval data type in postgres. > > pypgsql returns a DateTimeDelta instance when retrieving such values. > > Is there any plan to use RelativeDateTime, cause interval <-> > DateTimeDelta is destructive on client side. > > With DateTimeDelta, years can't be specified and all years haven't 365 > days. Even saying a year is 365.2425 days, working with months is worse > :( > > Any turn-around ? > > Or, if I want to do it myself, is interval2DateTimeDelta the only place > to look at for returning RelativeDateTime instead of DateTimeDelta ? > > Thanks for any help. > > François > > > ------------------------------------------------------- > This SF.net email is sponsored by: IBM Linux Tutorials. > Become an expert in LINUX or just sharpen your skills. Sign up for IBM's > Free Linux Tutorials. Learn everything from the bash shell to sys admin. > Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click > _______________________________________________ > Pypgsql-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/pypgsql-users >
pypgsql-rdt.diff
(application/octet-stream, 5.8 KB)
diff -r -d -u ../pypgsql/pyPgSQL/PgSQL.py pypgsql/pyPgSQL/PgSQL.py
--- ../pypgsql/pyPgSQL/PgSQL.py 2003-07-14 23:19:20.000000000 +0200
+++ pypgsql/pyPgSQL/PgSQL.py 2004-01-08 10:37:26.000000000 +0100
@@ -427,18 +427,16 @@
TimestampFromTicks = DateTime.TimestampFromTicks
#-----------------------------------------------+
-# The DateTimeDelta type for PgInterval support |
+# The RelativeDateTime type for PgInterval support |
#-----------------------------------------------+
-DateTimeDelta = DateTime.DateTimeDelta
+RelativeDateTime = DateTime.RelativeDateTime
#-------------------------------+
# Also the DateTime types |
#-------------------------------+
DateTimeType = DateTime.DateTimeType
-DateTimeDeltaType = DateTime.DateTimeDeltaType
-DateTimeDelta = DateTime.DateTimeDelta
#-----------------------------------------------------------------------+
# Name: DBAPITypeObject |
@@ -548,7 +546,13 @@
class TypeCache:
"""Type cache -- used to cache postgreSQL data type information."""
-
+
+ _time_units = (
+ ( 'day', 'days'),
+ ( 'month', 'mon', 'mons' ),
+ ( 'year', 'years'),
+ )
+
def __init__(self, conn):
if noWeakRef:
self.__conn = conn
@@ -560,34 +564,35 @@
def __callback(self, o):
self.__conn = None
- def interval2DateTimeDelta(self, s):
- """Parses PostgreSQL INTERVALs.
+ def interval2RelativeDateTime(self, s):
+ """Parses PostgreSQL INTERVALs.
The expected format is [[[-]YY years] [-]DD days] [-]HH:MM:SS.ss"""
- parser = DateTime.Parser.DateTimeDeltaFromString
-
- ydh = s.split()
- ago = 1
-
- result = DateTimeDelta(0)
-
- # Convert any years using 365.2425 days per year, which is PostgreSQL's
- # assumption about the number of days in a year.
- if len(ydh) > 1:
- if ydh[1].lower().startswith('year'):
- result += parser('%s days' % ((int(ydh[0]) * 365.2425),))
- ydh = ydh[2:]
-
- # Converts any days and adds it to the years (as an interval)
- if len(ydh) > 1:
- if ydh[1].lower().startswith('day'):
- result += parser('%s days' % (ydh[0],))
- ydh = ydh[2:]
-
- # Adds in the hours, minutes, seconds (as an interval)
- if len(ydh) > 0:
- result += parser(ydh[0])
-
- return result
+ tokens = s.split()
+ quantity = None
+ result = RelativeDateTime()
+ for token in tokens:
+ # looking for quantity
+ if token.isdigit() or token[0] == '-' and token[1:].isdigit():
+ quantity = int(token)
+ continue
+ # looking for unit
+ elif token.isalpha() and not quantity is None:
+ unitAttr = None
+ for unit in self._time_units:
+ if token in unit:
+ unitAttr = unit[0]
+ if unitAttr and not quantity is None:
+ setattr(result, unitAttr, quantity)
+ quantity = None
+ continue
+ # looking for time
+ elif token.find(':') != -1:
+ hms = [ int(value) for value in token.split(':') ]
+ result.hour = hms[0]
+ result.minute= hms[1]
+ if len(hms) == 3:
+ result.second = hms[2]
+ return result
def parseArray(self, s):
"""Parse a PostgreSQL array strings representation.
@@ -795,11 +800,11 @@
else:
return PgMoney(value).value
elif _ftv == DATETIME:
- if type(value) in [DateTimeType, DateTimeDeltaType]:
+ if type(value) is DateTimeType:
return value
else:
if _ftv == PG_INTERVAL:
- return self.interval2DateTimeDelta(value)
+ return self.interval2RelativeDateTime(value)
else:
return DateTime.ISO.ParseAny(value)
elif _ftv == BINARY:
@@ -2230,8 +2235,9 @@
_j = '%s%s,' % (_j, _i._quote(1))
elif type(_i) is DateTimeType:
_j = '%s"%s",' % (_j, _i)
- elif type(_i) is DateTime.DateTimeDeltaType:
- _j = '%s"%s",' % (_j, dateTimeDelta2Interval(_i))
+ elif isinstance(value, RelativeDateTime):
+ _j = '%s"%s",' % (_j, relativeDateTime2Interval(_i))
+
elif type(_i) is PgInt2Type or isinstance(_i, PgInt8Type):
_j = '%s%s,' % (_j, str(_i))
else:
@@ -2255,8 +2261,8 @@
return value._quote()
elif type(value) is DateTimeType:
return "'%s'" % value
- elif type(value) is DateTimeDeltaType:
- return "'%s'" % dateTimeDelta2Interval(value)
+ elif isinstance(value, RelativeDateTime):
+ return "'%s'" % relativeDateTime2Interval(value)
elif isinstance(value, StringType):
return PgQuoteString(value)
elif isinstance(value, LongType):
@@ -2286,28 +2292,19 @@
return t
-def dateTimeDelta2Interval(interval):
+def relativeDateTime2Interval(interval):
"""
-DateTimeDelta2Interval - Converts a DateTimeDelta to an interval string\n
- The input format is [+-]DD:HH:MM:SS.ss\n
- The output format is DD days HH:MM:SS.ss [ago]\n
+relativeDateTime2Interval - Converts a RelativeDateTime to an interval string\n
+ The output format is YYYY years M mons DD days HH:MM:SS\n
"""
-
- if type(interval) is DateTimeDeltaType:
- s = str(interval)
- ago = ''
- if s[0] == '-':
- ago = ' ago'
- s = s[1:]
- else:
- ago = ''
- s = s.split(':')
- if len(s) < 4:
- return '%s:%s:%s %s' % (s[0], s[1], s[2], ago)
-
- return '%s days %s:%s:%s %s' % (s[0], s[1], s[2], s[3], ago)
- else:
- raise TypeException, "DateTimeDelta2Interval requires a DataTimeDelta."
+ return "%s years %s mons %s days %02i:%02i:%02i" % (
+ interval.years,
+ interval.months,
+ interval.days,
+ interval.hours,
+ interval.minutes,
+ interval.seconds
+ )
#-----------------------------------------------------------------------+
# Name: Connection |