[Zope-dev] RFC: RelationAware class for relations between objects

roche@upfrontsystems.co.za roche@upfrontsystems.co.za
Mon, 28 Apr 2003 18:53:08 +0200


* Shane Hathaway <shane@zope.com> [2003-04-28 17:09]:
> roche@upfrontsystems.co.za wrote:
> >There has been a lot of discussion about the need for a service that
> >manages relations between objects on zope3-dev lately and in the past.
> >I thought this would be a good time to share some code we have written
> >to make relations a bit easier in Zope 2 and to invite some comments on
> >it. The attached module provides a mixin class that collaborates with
> >Max M's mxmRelations product almost like CatalogAwareness collaborates
> >with the ZCatalog. I really hope that this can be an acceptable interim
> >solution until relations are better managed by the ZODB or by some
> >service in Zope 3.
> 
> I'm going to take this opportunity to move the discussion here instead 
> of zope3-dev.

Great! Thanks for engaging this topic.

> Relations are important for any sizable application.  That means to me 
> that support for relations should not require the Zope application.  It 
> seems like relations shouldn't even require acquisition, context 
> wrapping, or a component architecture.  Currently, Zope 2 fulfills most 
> needs for relations using ZCatalog, but ZCatalog is a lot to swallow.
> 
> Jeremy posted some code that started to look like the right way to 
> create relations in ZODB.

I also think relations shouldn't require Zope and Jeremy sure shows that
it can be done in pure python. What I appreciate about this is that it
might provide a solution that might be workable with Zope 2 in the
interim and Zope 3 later on.

> http://mail.zope.org/pipermail/zope3-dev/2003-April/006720.html
> 
> Here are the important features that made it interesting:
> 
> - You describe relations in the same place you write classes.  The great 
> thing about an object-oriented database is that you can get so much done 
> just by writing classes.  But in the current ZODB, as soon as you need 
> flexible relationships, you have to move into a totally different 
> sphere, such as creating a ZCatalog or some kind of relationship 
> service.  It shouldn't be that way.  Python is expressive enough.

Absolutely! It is so natural in Python to assign an object to an
attribute of another object and reference that object later like any
other attribute. We basically just want to make the underlying storage
cope with this. There is one kind of relationship that already has these
natural qualities in the ZODB and that is containment. When one object
contains other objects it is already possible to say
Container.Content.Attribute. I mention this purely because it might
proof useful to keep this in mind when we think of other relationships.

> - Descriptors elegantly provide custom views on relations.  In the 
> example, "zope3.developers" looks like a set of Developer objects.

I haven't worked with descriptors before and forgot what they do. I
reread AMK's, "What's new in Python 2.2" to help me understand what it
is that Jeremy was doing. I must say that this is the kind of feature
that makes me a jubilant python developer.

> - All the implementation details, such as use of BTrees, was moved away 
> from the application code.  To me, this means that the default relation 
> implementation could be substituted depending on the capabilities of the 
> storage method.  Ape, for example, could implement relational queries by 
> translating to SQL.
> 
> Unfortunately, I didn't like Jeremy's revisions quite as much.  The 
> revised version creates two Relation objects instead of one.  Maybe I 
> just don't understand it yet, but it doesn't fit my brain. ;-)  I prefer 
> the notion of having two views on a single relation.

I agree. I was reluctant to specify relations between classes in the
class itself but the idea is growing on me *because* it is natural in
python: objectX.attr = objectY. I don't think that objects on both ends
of the relationship should necessarily know that they are related to. In
Jeremy's example this seems to be a requirement. In objextX.attr =
objectY, objectY doesn't know it is related two.

> I also feel that 
> having a many2many function might be oversimplifying, since I came up 
> with the need for a "many2many2many" function over the weekend.  That 
> would be wrong!

Won't this just be a chain of relations? You have to explain what you
came up with.

> We need to make sure the interface fits an existing, 
> well-researched model for relationships.  I only know about relational 
> tables, topic maps, and RDF.

I'd also like to know what models exist. I am not absolutely clear on
what the problem statement is. It seems that the problem lies with the
underlying persistence framework and not with relationships between
objects. The reason I say this is because we already know a natural way
to "relate" objects in pure python.

> 
> Max M: your example is useful and probably more manageable than 
> ZCatalogs.  But I think it would be more useful if it provided an easy 
> way to create relations in the code itself.  You only have a comment 
> that says the relation already exists.  Jeremy's example creates the 
> relation if it doesn't already exist, although it's only a basic 
> relation.  You example would also be enhanced by the use of descriptors.
> 
> Roche: your example is purely implementation, although the ideas look 
> interesting.  Try writing something similar to Jeremy's example to 
> evaluate the simplicity of your approach.

I have one requirement though and that is that it should work with Zope
2 (not require it). Zope 2 apps are my bread and butter at the moment
but for now I am going to assume that Zope 2 works fine with python 2.2
and that a descriptor based solution is the way to go.

> The current Zope 3 plan is to put all relation management in a service. 
>  As I see it, that is one possible implementation of Jeremy's 
> relation() function.  Also, I would be a little disappointed if creating 
> relations always required writing XML-based configuration documents or 
> visiting something in the management interface.  Instead, a little bit 
> of Python code ought to be sufficient.
> 
> Now, don't assume I really know what I'm talking about!

That makes two of us but at least if we don't know what we're talking
about nobody else will either and they can't blame us if we mess up and
they might even like us we come up with something good ;-)

> I'm not a database administrator, and I'm evaluating the proposed
> ideas both objectively and subjectively.  If nobody disagrees with me
> then I'll be afraid that nobody agrees, either. ;-)

I just have this itch and will bet on it that proper handling of
relationships will save tons of code.

-- 
Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za