On Jul 22, 2006, at 4:47 AM, Lorenzo Gil Sanchez wrote:
El vie, 21-07-2006 a las 10:21 -0400, Pete Taylor escribió:
I've run into a very (very!) similar situation, and ended up writing
some wrapper/simplification utilities for zc.relationship.
zc.relationship is wonderfully powerful, but a bit complex. It's use
is intuitive once you wade through the 2000+ lines of documentation
(which is worthwhile reading), but it's a bit intimidating at first.
Ok, I was afraid of an answer like this because in a recent thread
read Jim Fulton saying that we are trying to use zodb as a relational
database which is a shame and I think I agree with that quote.
So that's why I tried not to use external packages like
and stick to a plain object model with intrinsic relations modeled as
simple object attributes.
Heh. I gave that Jim Fulton quote, and encouraged the direction you
describe; *and* I wrote zc.relationship. ;-) They are not mutually
exclusive. Let's take a simple two-member directional relationship
as an example--something like "A depends on B".
If neither object should inherently know about the relationship--it's
not intrinsic to either of their data models--then it makes good
sense to have external relationship objects that model the
connection. The relationship container in zc.relationship is a
simple example of a solution for that use case.
If the relationship is intrinsic to one object's data model but not
to the other's, then it makes sense to have a Python pointer on the
first object. If you need to ask questions, such as simple
backpointers, then you can set up an extrinsic reference or you can
set up a zc.relationship index to index the first object. For a
simple backpointer case, an extrinsic reference is sufficient and
simpler. If you need more sophisticated queries than just
backpointers then the zc.relationship index can be a real win: you
can adapt the first object to a relationship interface that breaks
the relationship down into parts that match the queries you want to
make. That works nicely.
If the relationship is intrinsic to both objects' data models, all
you can really do is choose one of the previous two approaches and
put some sugar around it. AIUI, schooltool's relationship code does
something like this: you can specify both sides of a relationship in
a class definition (and an interface, I believe) and behind the
scenes it keeps track of the relationship for you in an external data
structure, no matter which side of the relationship you modify.
zc.relationship's index could be used to build functionality like
this, but it has not been done to my knowledge.
The obvious question is: does this allow
powerful queries like the ones I mentioned in my first email or I
switch and use extrinsic relations for this kind of features?
zc.relationship indexes can be combined with other catalog indexes to
do what you described, but doing so efficiently will require
knowledge of catalog indexes and the BTree module. The README for
zc.relationship touches on this when it discusses filters:
| If relationship tokens (from 'findRelationshipChains' or 'apply' or
| 'findRelationshipTokenSet', or in a filter to most of the search
| to be merged with other catalog results, relationship tokens should
| on intids, as in the default. For instance, if some relationships
| available to some users on the basis of security, and you keep an
| this, then you will want to use a filter based on the relationship
| viewable by the current user as kept by the catalog index.
The filter is not the only approach--you will sometimes want to merge
*results* from a relationship index and other indexes, for instance--
but if you are doing transitive searches it may be preferred for
zc.relationship is a bit of a powertool. Projects like the one Pete
describes to make a friendly, more constrained usage of it will be
Also, don't forget SQL. I prefer the ZODB, and stay there if I can
make a reasonably convincing case (almost always ;-) ), but sometimes
an app really calls out for a hybrid approach.
Zope3-users mailing list