Thread: [SQLObject] Overriding new()..._SO_new()?
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Brad B. <br...@bb...> - 2003-10-10 15:12:24
|
Hi, I would have thought it to be pretty common to want to customize what happens when a new SQLObject is created. In my case, I have to use cases at the moment: 1. I want the default of a date column in my Transaction object to be the time at which the object was created. 2. I want my other types of transactions (Purchase, Refund, ChargeBack, ServiceCharge, etc, etc) to be smart enough to accept all the arguments (in their new() method) of both their respective tables, and the transaction table, so that each one is smart enough to transparently add the necessary row to the transaction table. In both cases, I need to customize the behaviour of creating a new SQLObject. Am I missing a way in which this can be done, or should SQLObject have an _SO_new? -- Brad Bollenbach BBnet.ca |
From: Ian B. <ia...@co...> - 2003-10-10 15:29:07
|
On Friday, October 10, 2003, at 10:12 AM, Brad Bollenbach wrote: > Hi, > > I would have thought it to be pretty common to want to customize what > happens when a new SQLObject is created. > > In my case, I have to use cases at the moment: > > 1. I want the default of a date column in my Transaction object to be > the time at which the object was created. > > 2. I want my other types of transactions (Purchase, Refund, > ChargeBack, ServiceCharge, etc, etc) to be smart enough to accept all > the arguments (in their new() method) of both their respective tables, > and the transaction table, so that each one is smart enough to > transparently add the necessary row to the transaction table. > > In both cases, I need to customize the behaviour of creating a new > SQLObject. > > Am I missing a way in which this can be done, or should SQLObject have > an _SO_new? You can override new() just like it is. (Though number 1 can probably be handled with a column default) -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Brad B. <br...@bb...> - 2003-10-10 20:18:50
|
On Friday, October 10, 2003, at 11:23 AM, Ian Bicking wrote: >> Am I missing a way in which this can be done, or should SQLObject >> have an _SO_new? > > You can override new() just like it is. (Though number 1 can probably > be handled with a column default) Then what method do I call to access the "original" new once I've done the overriding? When overriding columns, I'd just use the _SO_'s, but when overriding new, it's unclear (to me, at least.) Also, I don't see how using a column default will be able to default a DateTimeCol to be the time at which the row was created, but in any case, I still want to override new for at least the problem of wanting to instantiate a Transaction when a Refund/Purchase/ChargeBack/whatever is instantiated. -- Brad Bollenbach BBnet.ca |
From: Brad B. <br...@bb...> - 2003-10-10 20:45:22
|
On Friday, October 10, 2003, at 04:18 PM, Brad Bollenbach wrote: > On Friday, October 10, 2003, at 11:23 AM, Ian Bicking wrote: >>> Am I missing a way in which this can be done, or should SQLObject >>> have an _SO_new? >> >> You can override new() just like it is. (Though number 1 can >> probably be handled with a column default) > > Then what method do I call to access the "original" new once I've done > the overriding? When overriding columns, I'd just use the _SO_'s, but > when overriding new, it's unclear (to me, at least.) Sidnei pointed out that I could do: super(Transaction, cls).new() which, as it turns out, Does The Right Thing. But I wonder if those are the kind of semantics one would want to use (if "one" is "me", the answer is "No" because There Is No Superclass(TM), so it seems like a misleading hackaround.) Just my $0.02 CAD. -- Brad Bollenbach BBnet.ca |
From: Ian B. <ia...@co...> - 2003-10-10 21:08:56
|
On Friday, October 10, 2003, at 03:18 PM, Brad Bollenbach wrote: > On Friday, October 10, 2003, at 11:23 AM, Ian Bicking wrote: >>> Am I missing a way in which this can be done, or should SQLObject >>> have an _SO_new? >> >> You can override new() just like it is. (Though number 1 can >> probably be handled with a column default) > > Then what method do I call to access the "original" new once I've done > the overriding? When overriding columns, I'd just use the _SO_'s, but > when overriding new, it's unclear (to me, at least.) _SO_get_colName is an exception, because the SQLObject class doesn't implement methods for your columns. But SQLObject implements new(), so you can call SQLObject.new(cls, **kw) (or use super()). > Also, I don't see how using a column default will be able to default a DateTimeCol > to be the time at which the row was created, but in any case, I still want to > override new for at least the problem of wanting to instantiate a Transaction when > a Refund/Purchase/ChargeBack/whatever is instantiated. You can use SQLBuilder.const.NOW(), which will put 'NOW()' into the insert, or you can have a default value of DateTime.now -- functions and methods will be called when an object is inserted, so if the default is DateTime.now then DateTime.now() will be inserted. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Brad B. <br...@bb...> - 2003-10-14 17:49:43
|
On Friday, October 10, 2003, at 05:08 PM, Ian Bicking wrote: > On Friday, October 10, 2003, at 03:18 PM, Brad Bollenbach wrote: >> On Friday, October 10, 2003, at 11:23 AM, Ian Bicking wrote: >>>> Am I missing a way in which this can be done, or should SQLObject >>>> have an _SO_new? >>> >>> You can override new() just like it is. (Though number 1 can >>> probably be handled with a column default) >> >> Then what method do I call to access the "original" new once I've >> done the overriding? When overriding columns, I'd just use the >> _SO_'s, but when overriding new, it's unclear (to me, at least.) > > _SO_get_colName is an exception, because the SQLObject class doesn't > implement methods for your columns. But SQLObject implements new(), > so you can call SQLObject.new(cls, **kw) (or use super()). I've hacked this in, but I still don't quite agree with this implementation-detail-reasoning, for a few reasons: 1. I'm calling SQLObject.new, instead of TableName.new. The "one class for one table" metaphor starts losing its balance -- I'm used to being able to look at the class on which new was called to see the name of the table in which the new() row will be created. That's no longer applicable here. 2. I have to pass the class instance to the SQLObject.new call, which is not the way I'm used to being able to call new. 3. Conceptually, I expect to think of new() as a "method created at runtime" too -- and therefore, provided with an _SO_ method like each column's property methods -- because (conceptually) it wouldn't know how to go about creating my columns until it knows what columns I've defined. The implementation detail, however, breaks the metaphor, IMHO. I'm either being reasonable, picky, stubborn, or all of the above, but in the discussion we had on IRC, Sidnei seemed to think _SO_new would be useful too. Thoughts? -- Brad Bollenbach BBnet.ca |
From: Ian B. <ia...@co...> - 2003-10-14 18:03:48
|
On Tuesday, October 14, 2003, at 12:49 PM, Brad Bollenbach wrote: > On Friday, October 10, 2003, at 05:08 PM, Ian Bicking wrote: > >> On Friday, October 10, 2003, at 03:18 PM, Brad Bollenbach wrote: >>> On Friday, October 10, 2003, at 11:23 AM, Ian Bicking wrote: >>>>> Am I missing a way in which this can be done, or should SQLObject >>>>> have an _SO_new? >>>> >>>> You can override new() just like it is. (Though number 1 can >>>> probably be handled with a column default) >>> >>> Then what method do I call to access the "original" new once I've >>> done the overriding? When overriding columns, I'd just use the >>> _SO_'s, but when overriding new, it's unclear (to me, at least.) >> >> _SO_get_colName is an exception, because the SQLObject class doesn't >> implement methods for your columns. But SQLObject implements new(), >> so you can call SQLObject.new(cls, **kw) (or use super()). > > I've hacked this in, but I still don't quite agree with this > implementation-detail-reasoning, for a few reasons: > > 1. I'm calling SQLObject.new, instead of TableName.new. The "one class > for one table" metaphor starts losing its balance -- I'm used to being > able to look at the class on which new was called to see the name of > the table in which the new() row will be created. That's no longer > applicable here. Sure you can access the table name and all that stuff. SQLObject.new(cls, **kw) calls the SQLObject.new *method*, but the *class* (cls) is still your TableName class. > 2. I have to pass the class instance to the SQLObject.new call, which > is not the way I'm used to being able to call new. That's just the way Python works, this is how you call a superclass. Or use super(cls).new(**kw), which should work fine too (except maybe in some early versions of 2.2 that are buggy). The two are equivalent. > 3. Conceptually, I expect to think of new() as a "method created at > runtime" too -- and therefore, provided with an _SO_ method like each > column's property methods -- because (conceptually) it wouldn't know > how to go about creating my columns until it knows what columns I've > defined. The implementation detail, however, breaks the metaphor, > IMHO. The only methods created at runtime are the column and join methods, because (from the SQLObject class's perspective) there are an unknown number of these methods, with unknown names. These created methods are all very small, and point to methods defined in the SQLObject class. > I'm either being reasonable, picky, stubborn, or all of the above, but > in the discussion we had on IRC, Sidnei seemed to think _SO_new would > be useful too. Yep, picky and stubborn ;) You could argue that SQLObject shouldn't use inheritance, and that the mechanics of persistence should be put in a separate object. This isn't unreasonable, and maybe it could happen at some time -- maybe Col and its subclasses would turn into descriptors (akin to property), and you'd define the mapping in some prescribed instance variable (and that mapping would subclass from some SQLObject class). But cls._SO_new vs. SQLObject.new is only a trivial side effect of subclassing. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |