On May 7, 2008, at 1:29 PM, Laurence Rowe wrote:
I'm thinking more about having the same classes mapped to different
databases at different points in the application. Imagine a
departmental address book app. Intstances of the departmental
address book are created for each department, each with a different
databases:
http://addressbook/sales -> postgres:///sales
http://addressbook/engineering -> postgres:///engineering
The way I imagine this working is to have a proxy engine object that
looks up the real engine through a local utility. Each application
would be a `site` and capable of local utility registrations. /sales
would have Engine('postgres:///sales') registered and /engineering
Engine('postgres:///engineering').
Only a single ScopedSession would be required. This would be bound
to proxy that performs the utility lookup. So when in the /sales
context the proxy would point to the sales engine and when in the /
engineering context to the engineering engine.
The limitation of this approach is that it would not be possible to
mix objects from /sales and objects from /engineering into the same
transaction. So really we need a session per application instance.
Perhaps this can be achieved through a custom scoping function:
def scopefunc():
return thread.get_ident(), id(zope.component.getSiteManager())
If you want to mix tables (and optionally engines) for the *same*
class, we actually have a feature for that too. Its sort of a feature
I've wanted to remove but Jason keeps arguing that its worthy. It's
called "entity_name" and it allows multiple primary mappers to be
created for a single class. The entity_name has to be specified when
you add the element to the session (yet another reason explicit add()
is a good thing). This feature is taken directly from the Hibernate
feature of the same name.
The limitation with entity_name which needs some more fixing in 0.5 is
that only one mapper gets to define the attribute instrumentation for
the entity. If you are storing the same class in three different
tables (across three different databases or just one), the attributes
defined on the class need to be compatible with all three. This is
reasonable since a class can only have one descriptor per attribute
name. Querying is also slightly challenging since the descriptors
need to be qualified for a particular mapper (i.e. you cant just say
query.filter(Address.id==5)...which "id" are we talking about ?)
The reason I'm not totally keen on this feature is that it seems to be
a very exotic way of getting around making simple subclasses, and I've
yet to see the use case for it where simple subclasses don't work,
except for "cosmetic" reasons which I have a hard time swallowing
(even if the reasons are "cosmetic", you can still create subclasses
that are all "named" the same).
So I will ask you, why can't your application simply have a
SalesAddress and an EngineeringAddress class ? You could even
produce them transparently using a custom __new__() method, i.e.
class Address(object):
def __new__(cls, *args, **kwargs):
if my_scoped_thing.context == 'sales':
return object.__new__(SalesAddress)
elif my_scoped_thing.context == 'engineering':
return object.__new__(EngineeringAddress)
this seems extremely straightforward to me as each object, once
instantiated is now bound for a specific destination. It doesnt seem
like youd want the *same* Address to be stored in one and then the
other in a different instance (that seems *extremely* complex for no
good reason). Isnt explicit better than implicit ?
_______________________________________________
Zope-Dev maillist - [email protected]
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )