Thread: [SQLObject] datetime column conversions
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Barry W. <ba...@py...> - 2005-01-05 18:01:18
|
I've just started using SQLObject -- I'm looking at it for a number of projects -- and I like it. Good work guys! I /really/ like not having to hand write all that SQL :). FTR, I'm using Python 2.4, SQLite 3.0.8, pysqlite 0.5.1, and SQLObject 0.6, all on a Gentoo Linux box. I'm having one immediate problem though. I have a DateTimeCol in one of my tables, and I set that column to an instance of a datetime.datetime object. That's all fine and good because SQLObject turns that into a string and stores it properly in the SQLite database. However, when I retrieve the column's value, I get a string back, not a datetime. I know that SQLite doesn't have a DATETIME type, but still, I would expect that if I store a value into a DateTimeCol, I would get a datetime back. My work around is simple, but it doesn't feel right: def string_to_date(s): stime =3D time.strptime(s, '%Y-%m-%d %H:%M:%S') secs =3D time.mktime(stime) return datetime.datetime.fromtimestamp(secs) class Thingie(sqlobject.SQLObject): # ... last_sent =3D DateTimeCol() def _get_last_sent(self): value =3D self._SO_get_last_sent() return string_to_date(s) This doesn't feel right because I have to do this transformation for every DateTimeCol attribute. I've only taken a cursory look at the code, but maybe it would be better to set a converter on the DateTimeCol class, or to subclass, but I haven't gotten either of those approaches to work. Ideally, DateTimeCol would just hand me datetime instances. ;) Suggestions, comments? Thanks, -Barry |
From: Oleg B. <ph...@ma...> - 2005-01-05 18:15:50
|
On Wed, Jan 05, 2005 at 01:01:01PM -0500, Barry Warsaw wrote: > I'm having one immediate problem though. I have a DateTimeCol in one of > my tables, and I set that column to an instance of a datetime.datetime > object. That's all fine and good because SQLObject turns that into a > string and stores it properly in the SQLite database. However, when I > retrieve the column's value, I get a string back, not a datetime. You are just in time! Please look the archive for this mailing list and reread messages for the last few days - the discussion about string-to-int conversion in the IntCol. Just today I commited a number of patches. Your problem is unfortunately a bit harder - what should toPython() returns - a string? a datetime instance? a mx.DateTime instance? Currently the column returns whatever the underlying driver returns. What database and driver do you use? Check out the code from Subversion's trunk and give it a try - there were a lot of bugs fixed since the release of SQLObject 0.6. 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-08 04:49:35
|
On Wed, 2005-01-05 at 13:15, Oleg Broytmann wrote: > On Wed, Jan 05, 2005 at 01:01:01PM -0500, Barry Warsaw wrote: > > I'm having one immediate problem though. I have a DateTimeCol in one o= f > > my tables, and I set that column to an instance of a datetime.datetime > > object. That's all fine and good because SQLObject turns that into a > > string and stores it properly in the SQLite database. However, when I > > retrieve the column's value, I get a string back, not a datetime. >=20 > You are just in time! Please look the archive for this mailing list > and reread messages for the last few days - the discussion about > string-to-int conversion in the IntCol. Just today I commited a number > of patches. I'm only now catching up, so I'm sure some of this has been covered in messages I've yet to get to. In general, I'm in agreement with you I think Oleg; Python's rule of "explicit is better than implicit" is the right one to adopt. Therefore I do not want SQLObject to implicitly convert from strings to ints. I'm fine if there are hooks or facilities to allow me to extend the basic column classes to get that if I want (which /I/ don't, but others might). As background, when I was with Zope, I worked on a system with some similarities to SQLObject, although not as general (and not open source). I found that it was important to split the notion of validators and converters (what we called "normalizers"). In this model, a validator only determines whether the value is of a valid format, returning true or false. The normalizer converted an acceptably formated value into a value suitable for storing into the column, or vice verse for the retrieval operation. Normalizers never raised type conversion exceptions because normalizers only ever accepted validated values. One of the areas where this level of flexibility really came in handy was in handling datetimes. ;) > Your problem is unfortunately a bit harder - what should toPython() > returns - a string? a datetime instance? a mx.DateTime instance? > Currently the column returns whatever the underlying driver returns. > What database and driver do you use? SQLite 3. And I know that it has no underlying DATETIME type, but as an application developer I shouldn't care. I've declared the column to be a DateTimeCol, I pass in a valid datetime instance, and I don't really care that it has to be stored as a string because I expect my application to get a datetime instance back again. If I stored an mx.DateTime I'd expect to get one of those back. To me, a string is not a valid datetime value so it should be rejected. More to follow as I continue to catch up... -Barry |
From: Oleg B. <ph...@ma...> - 2005-01-05 18:22:55
|
On Wed, Jan 05, 2005 at 01:01:01PM -0500, Barry Warsaw wrote: > def _get_last_sent(self): > value = self._SO_get_last_sent() > return string_to_date(s) > > This doesn't feel right because I have to do this transformation for > every DateTimeCol attribute. Subclass DateTimeCol and assign a validator for it. Look at UnicodeStringValidator and IntValidator for some examples. Make your validator as generic as possible, and publish the code for discussion. Let us decide if it needs to be added to the SQLObject. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Carlos R. <car...@gm...> - 2005-01-05 19:57:17
|
On Wed, 5 Jan 2005 21:15:40 +0300, Oleg Broytmann <ph...@ma...> wrote: > On Wed, Jan 05, 2005 at 01:01:01PM -0500, Barry Warsaw wrote: > > I'm having one immediate problem though. I have a DateTimeCol in one of > > my tables, and I set that column to an instance of a datetime.datetime > > object. That's all fine and good because SQLObject turns that into a > > string and stores it properly in the SQLite database. However, when I > > retrieve the column's value, I get a string back, not a datetime. > > You are just in time! Please look the archive for this mailing list > and reread messages for the last few days - the discussion about > string-to-int conversion in the IntCol. Just today I commited a number > of patches. > > Your problem is unfortunately a bit harder - what should toPython() > returns - a string? a datetime instance? a mx.DateTime instance? > Currently the column returns whatever the underlying driver returns. > What database and driver do you use? At the risk of sounding contentious (which I really don't want to), I'll repeat what I said on that very thread when mentioning Postel's law. The spirit is, "be strict when sending (to the db), and flexible when reading (from the db)". I believe that SQLObject could simply coerce the type to the one the user specified when he/she created the column object. On IntCol -> int() On FloatCol - > float() Obviously, DateTime presents a different problem because there is a clash between mx.DateTime and the std DateTime class. But in this case, one of two workarounds will probably work just as fine: 1. if mx.DateTime is available, use it. If not, use the std library version. 2. Allow the user to set which DateTime he prefers to use, by registering a coercion method. I don't think that this is the same as the validator, though... I assume that this could be done on the class itself, as in: DateTimeCol.DateTime = mx.DateTime.DateTime -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ph...> - 2005-01-05 20:58:50
|
On Wed, Jan 05, 2005 at 05:41:11PM -0200, Carlos Ribeiro wrote: > On IntCol -> int() > On FloatCol - > float() I disagree, you know. :) > 2. Allow the user to set which DateTime he prefers to use, by > registering a coercion method. I don't think that this is the same as > the validator, though... I assume that this could be done on the class > itself, as in: > > DateTimeCol.DateTime = mx.DateTime.DateTime This is the solution that I'm thinking about. But I think the better approach is to create two different subclasses of DateTimeCol (and SODateTimeCol) - one for datetime and another for mx.DateTime. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Max I. <ma...@uc...> - 2005-01-06 09:50:08
|
Oleg Broytmann wrote: >>2. Allow the user to set which DateTime he prefers to use, by >>registering a coercion method. I don't think that this is the same as >>the validator, though... I assume that this could be done on the class >>itself, as in: >> >>DateTimeCol.DateTime = mx.DateTime.DateTime > > > This is the solution that I'm thinking about. But I think the better > approach is to create two different subclasses of DateTimeCol (and > SODateTimeCol) - one for datetime and another for mx.DateTime. IMO, the approach to build a *whole class* just to provide a user with a custom type convertor is flawed. This feature should be directly supported by SQLObject. For example, by providing some protocol to register a coersion method, as Carlos suggests. |
From: Oleg B. <ph...@ma...> - 2005-01-06 10:15:53
|
On Thu, Jan 06, 2005 at 11:47:45AM +0200, Max Ischenko wrote: > register a coersion method, as Carlos suggests. class Converting(SQLObject): age = IntCol(validator=validators.Wrapper(fromPython=int), default=100) Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Max I. <ma...@uc...> - 2005-01-06 10:58:21
|
Oleg Broytmann wrote: >>register a coersion method, as Carlos suggests. > > > class Converting(SQLObject): > age = IntCol(validator=validators.Wrapper(fromPython=int), default=100) That's great. But why not: class Converting(SQLObject): age = IntCol(toPython=int, default=100) Yes, it's just a shortcut but it streamlines an API. Another use case. Here is my current version to plug-in my own currency type: class CurrencyMoneyValidator(validators.Validator): def fromPython(self, value, state): if isinstance(value, Money): return value.getValue() return value def toPython(self, value, state): if isinstance(value, float): return Money(value=value) return value class SOMoneyCol(SOCurrencyCol): def __init__(self, **kw): SOCurrencyCol.__init__(self, **kw) self.validator = validators.All.join( CurrencyMoneyValidator(), self.validator) class MoneyCol(Col): baseClass = SOMoneyCol IMO, it's clumsy and unnecessarily complex. I'd prefer something like this: class Foo(SQLObject): total = CurrencyCol(fromPython=convertFromMoney, toPython=Money) Hmm...after some thoughts, I don't really want to duplicate this declaration for every column of the currency type, but say it just once. After all, my current version does exactly that, if a bit verbose. ;-) Still, I'm eager to see a more succint notation for this particular use case. May be like this: MyCurrencyCol = Col.newClass(base=CurrencyCol, fromPython=lambda v: v.asString(), toPython=Money) Btw, have another question with regard to validators. See the class above: class CurrencyMoneyValidator(validators.Validator): def fromPython(self, value, state): if isinstance(value, Money): return value.getValue() return value def toPython(self, value, state): if isinstance(value, float): return Money(value=value) return value Here I have to check if passed in value is not None. Woudn't it be better if fromPython/toPython to be called if the value is *not* None - to get rid of these if statements. |
From: Barry W. <ba...@py...> - 2005-01-08 04:51:43
|
On Wed, 2005-01-05 at 14:41, Carlos Ribeiro wrote: > Obviously, DateTime presents a different problem because there is a > clash between mx.DateTime and the std DateTime class. But in this > case, one of two workarounds will probably work just as fine: >=20 > 1. if mx.DateTime is available, use it. If not, use the std library versi= on. >=20 > 2. Allow the user to set which DateTime he prefers to use, by > registering a coercion method. I don't think that this is the same as > the validator, though... I assume that this could be done on the class > itself, as in: >=20 > DateTimeCol.DateTime =3D mx.DateTime.DateTime I'd opt for option 2, but I would make datetime the default, since it's the data type that comes with Python (at least for 2.3 and beyond). -Barry |
From: Jorge L. G. F. <go...@ie...> - 2005-01-06 01:15:36
|
Oleg Broytmann, Quarta 05 Janeiro 2005 18:58, wrote: > On Wed, Jan 05, 2005 at 05:41:11PM -0200, Carlos Ribeiro wrote: >> On IntCol -> int() >> On FloatCol - > float() > > I disagree, you know. :) Hey! This is my text! I'm the one who disagrees ;-) I've been seeing messages on this subject and it seems to me that we are the only ones kind of reluctant to implement such an automatic conversion. One thing that I was thinking about was making it optional. Something like adding a parameter "auto_cast=False" (default) or "auto_cast=True" when instantiating the class. If it is true, then what is read from the database is passed through a conversion to the type it was supposed to be. Another option was to add a "cast_method=Method" where the default is "None". If it is a method then everything read from the database is passed to it (where one can make the cast to the desired type with some 'isinstance' checks of the object). It might be used for other things -- filters come to my mind -- too. Who knows both can be implemented if you have time :-) >> 2. Allow the user to set which DateTime he prefers to use, by >> registering a coercion method. I don't think that this is the same as >> the validator, though... I assume that this could be done on the class >> itself, as in: >> >> DateTimeCol.DateTime = mx.DateTime.DateTime > > This is the solution that I'm thinking about. But I think the better > approach is to create two different subclasses of DateTimeCol (and > SODateTimeCol) - one for datetime and another for mx.DateTime. Hmmm... maybe making it more generic as a class for the datetime available on the standard library and another class for external implementations that provide a minimal interface... But, then, this might be unnecessary complexity. -- Godoy. <go...@ie...> |
From: Carlos R. <car...@gm...> - 2005-01-06 09:25:26
|
On Wed, 05 Jan 2005 23:12:54 -0200, Jorge Luiz Godoy Filho <go...@ie...> wrote: > Another option was to add a "cast_method=Method" where the default is > "None". If it is a method then everything read from the database is passed > to it (where one can make the cast to the desired type with some > 'isinstance' checks of the object). It might be used for other things -- > filters come to my mind -- too. There is some overlap between the casting/coercion on read & the the validator, but I still feel that they are different. *If* for some reason automatic coercion is added to SQLObject, it should be: - only for the data received from the database; - configurable by providing a coercion function or some suitable class constructor. As for the suggestion to make it None... it's faster to use a lambda for this purpose. Something like this could be done: # standard implementation doNothing = lambda x: return x IntCol.coerceVal = doNothing DateTimeCol.coerceVal = doNothing # user customization IntCol.coerceVal = int DateTimeCol.coerceVal = datetime.datetime -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ma...> - 2005-01-06 10:15:11
|
On Wed, Jan 05, 2005 at 11:12:54PM -0200, Jorge Luiz Godoy Filho wrote: > One thing that I was thinking about was making it optional. Something like > adding a parameter "auto_cast=False" (default) or "auto_cast=True" when > instantiating the class. If it is true, then what is read from the > database is passed through a conversion to the type it was supposed to be. > > Another option was to add a "cast_method=Method" where the default is > "None". If it is a method then everything read from the database is passed > to it (where one can make the cast to the desired type with some > 'isinstance' checks of the object). It might be used for other things -- > filters come to my mind -- too. Easy: class Converting(SQLObject): age = IntCol(validator=validators.Wrapper(fromPython=int), default=100) Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Jorge L. G. F. <go...@ie...> - 2005-01-06 10:30:47
|
Oleg Broytmann, Quinta 06 Janeiro 2005 08:15, wrote: > On Wed, Jan 05, 2005 at 11:12:54PM -0200, Jorge Luiz Godoy Filho wrote: >> One thing that I was thinking about was making it optional. Something >> like adding a parameter "auto_cast=False" (default) or "auto_cast=True" >> when >> instantiating the class. If it is true, then what is read from the >> database is passed through a conversion to the type it was supposed to >> be. >> >> Another option was to add a "cast_method=Method" where the default is >> "None". If it is a method then everything read from the database is >> passed to it (where one can make the cast to the desired type with some >> 'isinstance' checks of the object). It might be used for other things -- >> filters come to my mind -- too. > > Easy: > > class Converting(SQLObject): > age = IntCol(validator=validators.Wrapper(fromPython=int), > default=100) I have to check the docs on this, but from "intuition", shouldn't it be "toPython", since the data is coming from the Database? The process of *sending* to the database should be checked, but how about what is read from there? This, IIUC, was the point. -- Godoy. <go...@ie...> |
From: Oleg B. <ph...@ma...> - 2005-01-06 11:19:47
|
On Thu, Jan 06, 2005 at 08:28:12AM -0200, Jorge Luiz Godoy Filho wrote: > > class Converting(SQLObject): > > age = IntCol(validator=validators.Wrapper(fromPython=int), > > default=100) > > I have to check the docs on this, but from "intuition", shouldn't it be > "toPython", since the data is coming from the Database? You can wrap both fromPython and toPython. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Carlos R. <car...@gm...> - 2005-01-06 11:29:55
|
On Thu, 6 Jan 2005 14:19:41 +0300, Oleg Broytmann <ph...@ma...> wrote: > On Thu, Jan 06, 2005 at 08:28:12AM -0200, Jorge Luiz Godoy Filho wrote: > > > class Converting(SQLObject): > > > age = IntCol(validator=validators.Wrapper(fromPython=int), > > > default=100) > > > > I have to check the docs on this, but from "intuition", shouldn't it be > > "toPython", since the data is coming from the Database? > > You can wrap both fromPython and toPython. I'm confused about it. AFAIK, SQLObject sits in the middle of the way: Python code <-> SQLObject <-> DB Driver I assume that the toPython & fromPython methods are supposed to be used in the interface between Python code & SQLObject. Using the same functions for the interface between SQLObject & DB driver seems kind of weird. Wouldn't it be better to have an equivalent pair of toDB & fromDB methods? -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ma...> - 2005-01-06 14:29:00
|
On Thu, Jan 06, 2005 at 09:29:52AM -0200, Carlos Ribeiro wrote: > I'm confused about it. AFAIK, SQLObject sits in the middle of the way: > > Python code <-> SQLObject <-> DB Driver > > I assume that the toPython & fromPython methods are supposed to be > used in the interface between Python code & SQLObject. Using the same > functions for the interface between SQLObject & DB driver seems kind > of weird. Wouldn't it be better to have an equivalent pair of toDB & > fromDB methods? SQLObject does not keep an internal representation. It keeps pythonic values, and convert them upon reading/writing fron/to DB. So, fromPython is your toDB, and toPython is fromDB. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Carlos R. <car...@gm...> - 2005-01-06 14:51:16
|
On Thu, 6 Jan 2005 17:28:52 +0300, Oleg Broytmann <ph...@ma...> wrote: > On Thu, Jan 06, 2005 at 09:29:52AM -0200, Carlos Ribeiro wrote: > > I'm confused about it. AFAIK, SQLObject sits in the middle of the way: > > > > Python code <-> SQLObject <-> DB Driver > > > > I assume that the toPython & fromPython methods are supposed to be > > used in the interface between Python code & SQLObject. Using the same > > functions for the interface between SQLObject & DB driver seems kind > > of weird. Wouldn't it be better to have an equivalent pair of toDB & > > fromDB methods? > > SQLObject does not keep an internal representation. It keeps > pythonic values, and convert them upon reading/writing fron/to DB. So, > fromPython is your toDB, and toPython is fromDB. In fact, SQLObject does maintain an internal representation. It has a optional cache to accelerate data access (see the calls to "setattr(self, instanceName(name), value)"). Also, on creation, it needs to store all data to do a single insert; and if _lazyUpdate is set, it also keeps the values in a local cache (ex: _SO_setValue on main.py). I really miss not being able to take some time to study SQLObject internals in depth right now. My gut feeling is that the architecture could be simplified by cleanly separating the roles (toPython & fromPython + toDB & fromDB), but I can't prove myself right now. -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ph...> - 2005-01-06 18:30:32
|
On Thu, Jan 06, 2005 at 12:51:14PM -0200, Carlos Ribeiro wrote: > On Thu, 6 Jan 2005 17:28:52 +0300, Oleg Broytmann <ph...@ma...> wrote: > > SQLObject does not keep an internal representation. It keeps > > pythonic values, and convert them upon reading/writing fron/to DB. So, > > fromPython is your toDB, and toPython is fromDB. > > In fact, SQLObject does maintain an internal representation. It has a > optional cache to accelerate data access (see the calls to > "setattr(self, instanceName(name), value)"). It keeps just the value, a Pythonic value. It returns it on read and converts to database format on write. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Jorge L. G. F. <go...@ie...> - 2005-01-06 12:20:45
|
Oleg Broytmann, Quinta 06 Janeiro 2005 09:19, wrote: > You can wrap both fromPython and toPython. Simultaneously? -- Godoy. <go...@ie...> |
From: Oleg B. <ph...@ma...> - 2005-01-06 14:27:05
|
On Thu, Jan 06, 2005 at 10:02:32AM -0200, Jorge Luiz Godoy Filho wrote: > Oleg Broytmann, Quinta 06 Janeiro 2005 09:19, wrote: > > > You can wrap both fromPython and toPython. > > Simultaneously? Yes. Read validators.py, class Wrap. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Ian B. <ia...@co...> - 2005-01-06 17:02:22
|
Jorge Luiz Godoy Filho wrote: > Oleg Broytmann, Quinta 06 Janeiro 2005 09:19, wrote: > > >> You can wrap both fromPython and toPython. > > > Simultaneously? Yes, that's the point of using validator objects instead of two independent conversion functions, because generally a transformation to the database has a corresponding transformation coming from the database. (Not always; e.g., when the driver does the transformation from the database) By putting them together, chaining them becomes a bit safer as well, since it's clearer what order they should be applied in. Honestly, that kind of chaining won't happen a whole lot in SQLObject, but in other situations it can. I've considered making these hooks easier to write, including the _set_columnName hooks. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Barry W. <ba...@py...> - 2005-01-08 04:55:23
|
On Wed, 2005-01-05 at 20:12, Jorge Luiz Godoy Filho wrote: > One thing that I was thinking about was making it optional. Something li= ke > adding a parameter "auto_cast=3DFalse" (default) or "auto_cast=3DTrue" wh= en > instantiating the class. If it is true, then what is read from the > database is passed through a conversion to the type it was supposed to be= . >=20 > Another option was to add a "cast_method=3DMethod" where the default is > "None". If it is a method then everything read from the database is pass= ed > to it (where one can make the cast to the desired type with some > 'isinstance' checks of the object). It might be used for other things -- > filters come to my mind -- too.=20 I think I would like to see a standard protocol or interface defined for these things. Then I could pass an instance of an object in that conformed to the protocol to do the type conversion in either or both directions (it shouldn't be required to include them both). If you decide to split validation and conversion, then those protocols would be defined too. I think it's fine to define the base column types as converting to and from the standard Python types. -Barry |
From: Ian B. <ia...@co...> - 2005-01-06 05:21:16
|
Oleg Broytmann wrote: >>2. Allow the user to set which DateTime he prefers to use, by >>registering a coercion method. I don't think that this is the same as >>the validator, though... I assume that this could be done on the class >>itself, as in: >> >>DateTimeCol.DateTime = mx.DateTime.DateTime > > > This is the solution that I'm thinking about. But I think the better > approach is to create two different subclasses of DateTimeCol (and > SODateTimeCol) - one for datetime and another for mx.DateTime. I don't think there should be two classes. A DateTimeCol isn't actually different than an MxDateTimeCol -- they both hold dates, they both look the same in the database. mx.DateTime and datetime should be selected with a keyword argument. Or, maybe it could be configured globally, since it's unlikely you'd want to use mx.DateTime in one place and datetime somewhere else; but I don't like assigning to a class variable like that. Maybe a class method, DateTimeCol.setDefaultImplementation(). In fact, it's just as good if it takes a string to indicate which implementation, since their interfaces are sufficiently different that you can't deal with the module in any abstract way. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Carlos R. <car...@gm...> - 2005-01-06 09:17:47
|
On Wed, 05 Jan 2005 23:21:09 -0600, Ian Bicking <ia...@co...> wrote: > Oleg Broytmann wrote: > >>2. Allow the user to set which DateTime he prefers to use, by > >>registering a coercion method. I don't think that this is the same as > >>the validator, though... I assume that this could be done on the class > >>itself, as in: > >> > >>DateTimeCol.DateTime = mx.DateTime.DateTime > > > > > > This is the solution that I'm thinking about. But I think the better > > approach is to create two different subclasses of DateTimeCol (and > > SODateTimeCol) - one for datetime and another for mx.DateTime. > > I don't think there should be two classes. A DateTimeCol isn't actually > different than an MxDateTimeCol -- they both hold dates, they both look > the same in the database. mx.DateTime and datetime should be selected > with a keyword argument. Or, maybe it could be configured globally, > since it's unlikely you'd want to use mx.DateTime in one place and > datetime somewhere else; but I don't like assigning to a class variable > like that. Maybe a class method, > DateTimeCol.setDefaultImplementation(). In fact, it's just as good if > it takes a string to indicate which implementation, since their > interfaces are sufficiently different that you can't deal with the > module in any abstract way. Although the interface is different, I believe that the signature of the constructor (which is what gets used for this kind of coercion) is the same. -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |