From: Barry W. <ba...@py...> - 2005-01-08 22:27:14
|
Okay, here's what I've come up with to do conversions to/from Python datetimes. class DateTimeValidator(validators.DateValidator): def fromPython(self, value, state): return value.strftime('%Y-%m-%d %H:%M:%S') def toPython(self, value, state): stime =3D time.strptime(value, '%Y-%m-%d %H:%M:%S') secs =3D time.mktime(stime) return datetime.datetime.fromtimestamp(secs) class MySODateTimeCol(SODateTimeCol): def __init__(self, **kw): SODateTimeCol.__init__(self, **kw) self.validator =3D validators.All.join( DateTimeValidator(), self.validator) class MyDateTimeCol(Col): baseClass =3D MySODateTimeCol This seems to work fine and I can live with it, but I had one thing that confused me, probably because I still don't fully grok how the validators and converters work. If I omit DateTimeValidator.fromPython(), then I get a traceback when I try to set a MyDateTimeCol. For example: class Notice(sqlobject.SQLObject): retrieved =3D MyDateTimeCol() text =3D StringCol() # later now =3D datetime.datetime.now() notice.set(text=3Dtext, retrieved=3Dnow) # ...traceback... File "/home/barry/projects/replybot/botlib/reply.py", line 36, in get_res= ponse notice.set(text=3Dtext, retrieved=3Dnow) File "/home/barry/projects/SQLObject/sqlobject/main.py", line 817, in set value =3D toPython(dbValue, self._SO_validatorState) File "/home/barry/projects/replybot/botlib/database.py", line 23, in toPy= thon stime =3D time.strptime(value, '%Y-%m-%d %H:%M:%S') File "/usr/local/lib/python2.4/_strptime.py", line 290, in strptime found =3D format_regex.match(data_string) TypeError: expected string or buffer This happens because main.py is finding a fromPython() that returns the datetime object unconverted, so when set() turns around and calls toPython on the value returned by fromPython, my fromPython gets a datetime when it only expected a string. I'm not sure if it's expected that validators.DateValidator.fromPython() should always return a string or not, but if I add that in my subclass, it seems like everything works. Anyway, there's the code FWIW. -Barry |
From: Oleg B. <ph...@ma...> - 2005-01-09 08:45:19
|
On Sat, Jan 08, 2005 at 05:27:05PM -0500, Barry Warsaw wrote: > Okay, here's what I've come up with to do conversions to/from Python > datetimes. > > class DateTimeValidator(validators.DateValidator): > def fromPython(self, value, state): > return value.strftime('%Y-%m-%d %H:%M:%S') > > def toPython(self, value, state): > stime = time.strptime(value, '%Y-%m-%d %H:%M:%S') > secs = time.mktime(stime) > return datetime.datetime.fromtimestamp(secs) Looks almost good. ("Almost" because your forgot about value=None that is mapped to SQL NULL; the format string should be parameterized.) I will test it, extend for mxDateTime, and apply. > I'm not sure if it's expected that validators.DateValidator.fromPython() > should always return a string or not It should return anything that toPython() groks. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Barry W. <ba...@py...> - 2005-01-09 15:27:09
|
On Sun, 2005-01-09 at 03:45, Oleg Broytmann wrote: > On Sat, Jan 08, 2005 at 05:27:05PM -0500, Barry Warsaw wrote: > > Okay, here's what I've come up with to do conversions to/from Python > > datetimes. > Looks almost good. ("Almost" because your forgot about value=3DNone > that is mapped to SQL NULL; the format string should be parameterized.) > I will test it, extend for mxDateTime, and apply. Heh, yep, I found that out and added it to my implementation after I sent my original message. -Barry |
From: Oleg B. <ph...@ph...> - 2005-01-09 11:57:26
|
On Sat, Jan 08, 2005 at 05:27:05PM -0500, Barry Warsaw wrote: > Okay, here's what I've come up with to do conversions to/from Python > datetimes. > > class DateTimeValidator(validators.DateValidator): I extended it, added MXDateTimeValidator and commited at revision 523 (inheritance bracnh - 524.) I also added a simple test for DateCol and DateTimeCol. The module sqlobject.col now exports a number of new constants. The most interesting are datetime_available (False in Python 2.2), mxdatetime_available and default_datetime_implementation. Default default_datetime_implementation is whatever is available. If both datetime and mxDateTime are available SQLObject will use datetime. You can change it BEFORE declaring your tables: from sqlobject import * if datetime_available and mxdatetime_available: from sqlobject import col col.default_datetime_implementation = DATETIME_IMPLEMENTATION ...or... col.default_datetime_implementation = MXDATETIME_IMPLEMENTATION Please note that the validators change date/time objects if passed a wrong type from a database driver or from the a program. That is, if both datetime and mxDateTime are available, and a column implentation is datetime (or mxDateTime), and a driver or a program passes mxDateTime (or datetime) object - the validator change it to datetime (mxDateTime, respectively). > One other thing, at the bottom of col.py, you export all subclasses of > Col in sqlobject.col's __all__. Should you also export all subclasses > of SOCol too? Done. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Barry W. <ba...@py...> - 2005-01-09 15:32:01
Attachments:
col-patch.txt
|
On Sun, 2005-01-09 at 06:57, Oleg Broytmann wrote: > I extended it, added MXDateTimeValidator and commited at revision 523 > (inheritance bracnh - 524.) I also added a simple test for DateCol and > DateTimeCol. > > The module sqlobject.col now exports a number of new constants. The > most interesting are datetime_available (False in Python 2.2), > mxdatetime_available and default_datetime_implementation. > Default default_datetime_implementation is whatever is available. If > both datetime and mxDateTime are available SQLObject will use datetime. > You can change it BEFORE declaring your tables: > > from sqlobject import * > if datetime_available and mxdatetime_available: > from sqlobject import col > col.default_datetime_implementation = DATETIME_IMPLEMENTATION > ...or... > col.default_datetime_implementation = MXDATETIME_IMPLEMENTATION In general, after a quick svn up and check it looks good. One problem though; you should default DATETIME_IMPLEMETNATION and MXDATETIME_IMPLEMENTATION to None otherwise "from sqlobject.col import *" will fail with an AttributeError. See attached. > Please note that the validators change date/time objects if passed a > wrong type from a database driver or from the a program. That is, if > both datetime and mxDateTime are available, and a column implentation is > datetime (or mxDateTime), and a driver or a program passes mxDateTime > (or datetime) object - the validator change it to datetime (mxDateTime, > respectively). Hmm, couldn't this incur a lot of churn if your program somehow ends up passing mixed datetime types? I'm personally not worried about it because I know I'll always use Python's built-in datetime objects, but I wonder if it might not be better to raise an exception? I don't feel strongly either though. > > One other thing, at the bottom of col.py, you export all subclasses of > > Col in sqlobject.col's __all__. Should you also export all subclasses > > of SOCol too? > > Done. Thanks! -Barry |
From: Oleg B. <ph...@ph...> - 2005-01-09 17:06:03
|
On Sun, Jan 09, 2005 at 10:31:54AM -0500, Barry Warsaw wrote: > In general, after a quick svn up and check it looks good. One problem > though; you should default DATETIME_IMPLEMETNATION and > MXDATETIME_IMPLEMENTATION to None otherwise "from sqlobject.col import > *" will fail with an AttributeError. See attached. I think I just fixed this and many other problems in revisions 525 (inheritance 526). Check it out and report, please. I also separated tests for datetime and mxDateTime. > > Please note that the validators change date/time objects if passed a > > wrong type from a database driver or from the a program. That is, if > > both datetime and mxDateTime are available, and a column implentation is > > datetime (or mxDateTime), and a driver or a program passes mxDateTime > > (or datetime) object - the validator change it to datetime (mxDateTime, > > respectively). > > Hmm, couldn't this incur a lot of churn if your program somehow ends up > passing mixed datetime types? No. Postgres drivers (both psycopg and pygresql) uncoditionally returns mxDateTime (or strings), regardless of your using datetime or mxDateTime. They are just too old and not very actively updated. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Barry W. <ba...@py...> - 2005-01-11 14:13:04
|
On Sun, 2005-01-09 at 12:05, Oleg Broytmann wrote: > On Sun, Jan 09, 2005 at 10:31:54AM -0500, Barry Warsaw wrote: > > In general, after a quick svn up and check it looks good. One problem > > though; you should default DATETIME_IMPLEMETNATION and > > MXDATETIME_IMPLEMENTATION to None otherwise "from sqlobject.col import > > *" will fail with an AttributeError. See attached. >=20 > I think I just fixed this and many other problems in revisions 525 > (inheritance 526). Check it out and report, please. > I also separated tests for datetime and mxDateTime. BTW, this is all working flawlessly now. I hope to release the fruits of this experiment within a few days. > > > Please note that the validators change date/time objects if passed= a > > > wrong type from a database driver or from the a program. That is, if > > > both datetime and mxDateTime are available, and a column implentation= is > > > datetime (or mxDateTime), and a driver or a program passes mxDateTime > > > (or datetime) object - the validator change it to datetime (mxDateTim= e, > > > respectively). > >=20 > > Hmm, couldn't this incur a lot of churn if your program somehow ends up > > passing mixed datetime types? >=20 > No. Postgres drivers (both psycopg and pygresql) uncoditionally > returns mxDateTime (or strings), regardless of your using datetime or > mxDateTime. They are just too old and not very actively updated. Okay. Taking nothing away from mxDateTime, it sure is nice that modern Pythons have decent built-in datetime types. -Barry |