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

Shane Hathaway shane@zope.com
Tue, 29 Apr 2003 11:24:09 -0400


Jeremy Hylton wrote:
>>- 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.
> 
> 
> I'm not quite sure what all the implementation details are.  Can you say
> more about how you would implement relations in Ape?

Basically, Ape would replace the implementation of the relation 
constructor and wire up relational queries directly to the database. 
Ape would probably not use BTrees at all.

I should mention that Ape is the reason I'm especially interested in 
relations at the moment.  We need a simple model that Ape can 
transparently replace with its own implementation.

> class SoftwareProject(object):
> 
>     developers = Relation()
>     
>     def __init__(self, name):
>         self.name = name
> 
> class Developer(object):
> 
>     projects = Relation()
>     
>     def __init__(self, name):
>         self.name = name
> 
> join(many(SoftwareProject.developers),
>      many(Developer.projects))
> 
> Does this version of the API look any better?

Okay, I see what you're saying now.  There really are two relations. 
Adding to one relation causes a new entry in the other relation.

What I see lacking is a clear way to expand this model.  If I could map 
this onto a relational table, I'd know how to build indexes, create more 
complex relationships, etc.  But this model looks unfamiliar, so I think 
we'll have to invent our own ways of expanding it.  Maybe I just haven't 
thought about it long enough.

> Can you post a simple example of many2many2many?  It would surely be
> simpler to spell with the join() function above.

I posted my floundering attempt at many2many2many this morning in my 
reply to Roche.  I tried to write a student registration system, where a 
student is registered in a particular course for a particular 
term/quarter/semester.  It's hard to view such a system in terms of only 
Student->Course and Course->Student relationships.  Instead, I view it 
as a database of Registration objects.  Here is a sketch of the way I'd 
see it:


class IRegistration (Interface):
     student = Attribute('student', 'A Student object')
     course = Attribute('course', 'A Course object')
     term = Attribute('term', 'A Term object')

registrations = RelationBuilder(IRegistration)


class Registration (Persistent):
     implements(IRegistration)
     def __init__(self, student, course, term):
         self.student = student
         self.course = course
         self.term = term

class Term (Persistent):
     def __init__(self, name):
         self.name = name

class Student (Persistent):
     current_courses = registrations.view(
         select='course', term='current')
     all_courses = registrations.view(
         select='course')

class Course (Persistent):
     current_students = registrations.view(
         select='student', term='current')
     all_students = registrations.view(
         select='student')


IRegistration would be better represented as a schema, but I don't have 
a schema syntax reference card handy.  ;-)  RelationBuilder creates a 
database table that looks quite similar to a table in a relational 
database, except that it refers to persistent objects rather than 
storing just strings and numbers.

>>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 don't know much about any of these.  From what little I know of RDF,
> it seems an example to avoid for this work.  I've never heard of "topic
> maps."

It's not directly relevant to this discussion, but here is where I 
learned about the relationship between relational databases, RDF, and 
topic maps:

http://www.w3.org/DesignIssues/RDB-RDF.html
http://www.ontopia.net/topicmaps/materials/tmrdfoildaml.html

FWIW, I just discovered that W3C invented a way to map between topic 
maps and RDF, so that means I don't have to learn about topic maps. :-)

http://www.w3.org/2002/06/09-RDF-topic-maps/

> I know that the ODMG object database standard has binary relationships,
> that is relationships between pairs of objects.  I don't really
> understand how an object database extends to relationships among many
> objects, since a pointer just points to one thing.  I'd be quite
> interested to see how a 3-way relationship worked in ZODB.

The example I gave above hopefully shows how n-way relationships might 
work.  If we implemented relationships that way, we could also provide 
shortcuts so that people can build binary relationships without having 
to write an interface.

Shane