Hello everybody,
some time ago I was writing about a patch I had written, to allow pgdb
handle datetime data... the remarks I received made me refine my
patch...
first the description, take it as a proposal, the patch (based on r3.8)
is attached. as a proposal, it is "what I understood" and consequently
"what I tried to implement". I'm obviously interested in comments, and
I'm prepared to accept the hardest criticism.
in python 2.1 the module datetime has been introduced, which makes
mx.DateTime superfluous. I'm switching to that module.
well ... support for mx.DateTime, that is now missing. one would
need to inform the library if he wants to use datetime or mx.DateTime...
you cannot base the choice on the simple availability of any of the two...
I did not look for a solution to this problem.
anyways: the datetime module offers the three types date, datetime, timedelta.
datetime.date has granularity at 1 day.
datetime.datetime has granularity as 1us (microsecond)
datetime.timedelta represents the result of a subtraction between
date(time) objects (granularity? microsecond too?)
in postgresql the above three types correspond to
DATE
TIMESTAMP
INTERVAL
an application making use of pgdb.py wanting to talk german, italian or
japanese with the user will do so on the users' side, but will still
talk ISO with the database. as a result, value conversions from and to
the database make use of the standard ISO formats.
so, what do you think about the assumptions?
here comes my patch. it seems to work for me...
looking forward to reading comments.
Mario Frasca.
--
Slight disorientation after prolonged system uptime is normal for new Linux
users. Please do not adjust your browser.
Index: pgdb.py
===================================================================
RCS file: /cvsroot/ibo/ibo3/python/PyGreSQL/pgdb.py,v
retrieving revision 3.8
diff -b -B -U3 -r3.8 pgdb.py
--- pgdb.py 25 Feb 2006 11:25:04 -0000 3.8
+++ pgdb.py 23 Jul 2006 13:18:31 -0000
@@ -4,7 +4,7 @@
#
# Written by D'Arcy J.M. Cain
#
-# $Id: pgdb.py,v 3.8 2006/02/25 11:25:04 mfrasca Exp $
+# $Id: pgdb.py,v 3.8.2.5 2006/07/23 07:32:28 mfrasca Exp $
#
"""pgdb - DB-API 2.0 compliant module for PygreSQL.
@@ -67,14 +67,14 @@
import types
import time
+revision = "$Revision: 3.8.2.5 $"[11:-2]
+
from _pg import *
-try: # use mx.DateTime module if available
- from mx.DateTime import DateTime, \
- TimeDelta, DateTimeType
-except ImportError: # otherwise use standard datetime module
- from datetime import datetime as DateTime, \
- timedelta as TimeDelta, datetime as DateTimeType
+from datetime import \
+ datetime as DateTime, datetime as DateTimeType, \
+ timedelta as TimeDelta, timedelta as TimeDeltaType, \
+ date as DateDate, date as DateType
### module constants
@@ -116,8 +116,24 @@
value = string.replace(value, "$", "")
value = string.replace(value, ",", "")
value = float(value)
- elif typ == DATETIME:
- # format may differ ... we'll give string
+ elif typ == TIMEDATE:
+ parts = [int(i) for i in value.split("-")]
+ value = DateDate(*parts)
+ pass
+ elif typ == TIMESTAMP:
+ f = value + ".000000"
+ import re
+ parts = re.split(r"[\. :-]", f)[:7]
+ parts[6] = (parts[6]+'000000')[:6]
+ parts = [int(i) for i in parts]
+ value = DateTime(*parts)
+ pass
+ elif typ == TIMEINTERVAL:
+ import re
+ value = re.sub('[a-z]', '', value)
+ parts = re.split(r"[ :-]+", value)
+ days, hours, minutes, seconds = [float(i) for i in parts]
+ value = TimeDelta(int(days), seconds+60*(minutes+60*hours))
pass
elif typ == ROWID:
value = long(value)
@@ -265,10 +281,14 @@
def _quote(x):
if isinstance(x, DateTimeType):
x = str(x)
+ elif isinstance(x, DateType):
+ x = str(x)
+ elif isinstance(x, TimeDeltaType):
+ x = str(x)
elif isinstance(x, unicode):
x = x.encode( 'utf-8' )
- if isinstance(x, types.StringType):
+ if isinstance(x, types.StringTypes):
x = "'" + string.replace(
string.replace(str(x), '\\', '\\\\'), "'", "''") + "'"
elif isinstance(x, (types.IntType, types.LongType, types.FloatType)):
@@ -280,7 +300,7 @@
elif hasattr(x, '__pg_repr__'):
x = x.__pg_repr__()
else:
- raise InterfaceError, 'do not know how to handle type %s' %
type(x)
+ raise InterfaceError, 'do not know how to write type %s to postgresql'
% type(x)
return x
@@ -415,8 +435,14 @@
MONEY = pgdbType('money')
# this may be problematic as type are quite different ... I hope it won't hurt
-DATETIME = pgdbType(
- 'abstime', 'reltime', 'tinterval', 'date', 'time', 'timespan',
'timestamp', 'timestamptz', 'interval'
+TIMEDATE = pgdbType(
+ 'date',
+)
+TIMESTAMP = pgdbType(
+ 'abstime', 'reltime', 'time', 'timestamp', 'timestamptz'
+)
+TIMEINTERVAL = pgdbType(
+ 'tinterval', 'timespan', 'interval'
)
# OIDs are used for everything (types, tables, BLOBs, rows, ...). This may
cause
@@ -428,7 +454,7 @@
# mandatory type helpers
def Date(year, month, day):
- return DateTime(year, month, day)
+ return DateDate(year, month, day)
def Time(hour, minute, second):
return TimeDelta(hour, minute, second)
_______________________________________________
PyGreSQL mailing list
[email protected]
http://mailman.vex.net/mailman/listinfo/pygresql