Been thinking about how to marshal from a set of values stored in the
DB to an object and want to share what I have come up with.
The following has two sections: my misunderstanding of what SQLObject
currently does (Ian, be patient with me) and a possible alternative
approach.
1. SQLObject
------------
It seems to me that database columns translate to properties in
SQLObject and that the setter method of the property also triggers an
UPDATE query (while the insert query is handled by the new method,
not attribute access).
Important is probably that there are no explicit database methods such
as insert (store, save) and update. This is done implicitly while
using the object (i.e., attribute access).
When SQLObject retrieves an object from the db, it first gets a list
of column values and then calls the objects class (eg., p=Person()) to
create an object instance and then sets all the values. [I derive
this from the statement from the manual that "__init__ is called
everytime an object is just fetched from the cache"].
What in plain python classes normally goes in __init__ should go in
the _init method for SQLObject subclasses. _init seems to be called
by SQLObject's new method.
2. Possible Alternative Approach
--------------------------------
A possible alternative approach makes a major change in the look and
feel inassuch that persistence methods (insert, update, ..) need to be
called explicitly.
My current intuition is that this is a good choice although I haven't
cristallized the reasons out very clearly. The following matters for
my intuition:
* it allows the use of temporary object (without ever storing them in
the db
* if we use transactions, we need to deal with storage issues anyhow
* same goes for resolution of collisions in concurrancy control. I
don't see a way of hiding these issues from the application
programmer
So in this case, column values could be stored in normal attributes
(in the __dict__) without the need for properties that overload the
setter method to update the db.
To retrieve an object from the db, a first step retrieves the column
values, then creates an empty object using <class>.__new__(<class>)
(thus avoiding __init__) and then assign the (unmarshelled) values to
the __dict__ (or better through use of normal setattr).
The advantages of this seem to be that objects behave much more like
normal python objects including:
* __init__ is just normal
* I believe (haven't verified) that it should be possible for users
to define properties in lieu of just normal __dict__ items without
any adverse effects. (I reason that the use of getattr and
setattr by the middleware works equally well)
I hope this was of interest to someone (has anyone gotten that far
reading) and am hoping for comments and being straightened out if I
got it wrong...
cheers
--b
/-----------------------------------------------------------------
| Bud P. Bruegger, Ph.D.
| Sistema (www.sistema.it)
| Via U. Bassi, 54
| 58100 Grosseto, Italy
| +39-0564-411682 (voice and fax)
\-----------------------------------------------------------------
|