|
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
|