From: Luke O. <lu...@me...> - 2004-02-17 16:57:47
|
> cust_account - main table > buyer - contact name, relates to customer account > buyer_info - contact address info, relates to buyer > county - relates to customer > shipping_rates - relates to customer > > Note that from the standpoint of the cust_account object, these are all > one-to-one relations. It should be relatively simple to traverse these > relations and present the attributes of the sub-tables as attributes of the > root class. I will call these 'proxy attributes'. If x is an instance of our > cust_account class, I should be able to do 'print x.email_addr' and get the > address of the buyer back. Obviously this only works if there is one > traversal path across the tables- one-to-one relationships. Exposing those > proxy attributes as properties of the root object is in the object-oriented > spirit of 'present the interface, hide the implementation'. There would need > to be some way of handling duplicate column names. We could either mandate > unique column names or provide a way to use aliases. Yes, so long as these are all one-to-one, it makes sense. I don't think there's a need for worrying about unique column names, that's something you need to resolve at your main object interface level. Any automated aliasing scheme would seem to expose implementation in awkward ways. But I could be wrong. > A conceptual difference is that I do not ever intend to create classes for > minor tables. There will be objects for all the major components like > employees and customers, and there will be objects like invoices that have a > master-detail structure that will be exposed from attributes like > 'line_items'. I will not be joining SQLObjects directly. I think you may have an issue here. What benefits are you getting from SQLObject if you don't model those 'private' tables? I have similar database setups (presenting multiple tables as unified objects), and model the entire implementation. When you say you don't want to create objects for all tables, I'm thinking you don't want your implementation-specific objects to be part of your public interface, but I don't think you're going to get the ease of implementing these proxies in SQLObject without having private objects for every relevant table. class CustomerAccount(SQLObject): # private composition _buyer = ForeignKey('Buyer') # public proxy def _get_emailAddr(self): # this could also have proxy at Buyer obj to buyerInfo, so like: # return self._buyer.emailAddr == return self._buyer.buyerInfo.emailAddr makes this work: x = CustomerAccount(id) print x.emailAddr Now, we could probably make this Proxy/Composition concept more automatic, whether with nested classes or a Col-like object with name->proxyCol mappings: class CustomerAccount(SQLObject): # nested class Buyer(SOProxy): _proxyClass = 'Buyer' # defaults from class name? # with second-level proxy as above emailAddr = 'emailAddr' # or emailAddr = 'buyerInfo.emailAddr' # col-like, have to be smart about multiple proxies to same class. emailAddr = Proxy('Buyer', 'buyerInfo.emailAddr') Does this fit into your goals? No matter what, I don't see how you're going to get around your middle layer explicitly describing these mappings from the database implementation to your chosen public object interface. - Luke |