
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@649 fd906abe-77d9-0310-91a1-e0d9ade77398
101 lines
3 KiB
Text
101 lines
3 KiB
Text
Yet Another Relations Engine...
|
|
===============================
|
|
|
|
Let's start with two classes and a few objects that we will connect using
|
|
relations:
|
|
|
|
>>> class Person(object):
|
|
... pass
|
|
|
|
>>> class City(object):
|
|
... pass
|
|
|
|
>>> clark = Person()
|
|
>>> kirk = Person()
|
|
>>> audrey = Person()
|
|
>>> washington = City()
|
|
>>> newyork = City()
|
|
|
|
The relation we'll use tells us in which city a person lives; this is a dyadic
|
|
relation as it connects two objects. We also associate the relationship
|
|
with an interface as we will later use this interface for querying relations.
|
|
|
|
Dyadic Relations
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
>>> from cybertools.relation import DyadicRelation
|
|
>>> class LivesIn(DyadicRelation):
|
|
... pass
|
|
|
|
We don't directly keep track of relations but use a relations registry for
|
|
this. The relations registry is usually a local utility; for testing we use
|
|
a simple dummy implementation:
|
|
|
|
>>> from cybertools.relation.registry import DummyRelationsRegistry
|
|
>>> relations = DummyRelationsRegistry()
|
|
|
|
So we are ready to connect a person and a city using the LivesIn relationship:
|
|
|
|
>>> relations.register(LivesIn(clark, washington))
|
|
>>> relations.register(LivesIn(audrey, newyork))
|
|
>>> relations.register(LivesIn(kirk, newyork))
|
|
|
|
We can now query the relations registry to find out where clark lives and
|
|
who lives in New York. For this we use the standard attributes of dyadic
|
|
relations, first and second:
|
|
|
|
>>> clarkRels = relations.query(first=clark)
|
|
>>> len(clarkRels)
|
|
1
|
|
>>> clarkRels[0].second == washington
|
|
True
|
|
|
|
>>> nyRels = relations.query(second=newyork)
|
|
>>> len(nyRels)
|
|
2
|
|
|
|
It is also possible to remove a relation from the relation registry:
|
|
|
|
>>> relations.unregister(
|
|
... relations.query(first=audrey, second=newyork)[0]
|
|
... )
|
|
>>> nyRels = relations.query(second=newyork)
|
|
>>> len(nyRels)
|
|
1
|
|
>>> nyRels[0].first == kirk
|
|
True
|
|
|
|
Triedic Relations
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
We now extend our setting using a triadic relationship - triadic relations
|
|
connect three objects. (If you want to connect more than three objects you
|
|
may use combinations of triadic and dyadic relations.)
|
|
|
|
>>> from cybertools.relation import TriadicRelation
|
|
>>> class ParentsOf(TriadicRelation):
|
|
... """ first (father) and second (mother) are the parents of
|
|
... third (child)."""
|
|
|
|
>>> relations.register(ParentsOf(clark, audrey, kirk))
|
|
|
|
When we search for relations that contain clark as first we get both:
|
|
|
|
>>> clarkRels = relations.query(first=clark)
|
|
>>> len(clarkRels)
|
|
2
|
|
|
|
So we want to look only for ParentsOf relationships - this should give us
|
|
all relations for clark's children:
|
|
|
|
>>> clarkChildren = relations.query(relationship=ParentsOf, first=clark)
|
|
>>> len(clarkChildren)
|
|
1
|
|
>>> clarkChildren[0].second == audrey
|
|
True
|
|
>>> clarkChildren[0].third == kirk
|
|
True
|
|
|
|
Setting up and using a RelationsRegistry local utility
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|