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