Package relmgr
Lightweight Object Database Class - API.
Expand source code
# __init__.py
"""
Lightweight Object Database Class - API.
"""
from relmgr.relationship_manager import RelationshipManager
# Version of relationship-manager package
__version__ = "2.0.2"
__all__ = ["RelationshipManager"] # support "from relmgr import *"" syntax
Sub-modules
relmgr.relationship_manager
-
Relationship Manager …
Classes
class RelationshipManager (caching: bool = True)
-
This is the Relationship Manager class to instantiate and use in your projects.
Constructor. Set the option
caching
if you want faster performance using Pythonlru_cache
technology - defaults to True.Expand source code
class RelationshipManager(): """This is the Relationship Manager class to instantiate and use in your projects.""" def __init__(self, caching: bool = True) -> None: """Constructor. Set the option `caching` if you want faster performance using Python `lru_cache` technology - defaults to True. """ if caching: self.rm = _RelationshipManagerCaching() else: self.rm = _EnforcingRelationshipManager() self.objects = _Namespace() """Optional place for storing objects involved in relationships, so the objects are saved. Assign to this `.objects` namespace directly to record your objects for persistence puposes. """ def _get_relationships(self) -> List[Tuple[object, object, Union[int, str]]]: """Getter""" return self.rm._get_relationships() def _set_relationships(self, listofrelationshiptuples: List[Tuple[object, object, Union[int, str]]]) -> None: self.rm._set_relationships(listofrelationshiptuples) """Setter""" relationships = property(_get_relationships, _set_relationships) """Property to get flat list of relationships tuples""" def add_rel(self, source, target, rel_id=1) -> None: """Add relationships between `source` and `target` under the optional relationship id `rel_id`. The `source` and `target` are typically Python objects but can be strings. The `rel_id` is a string or integer and defaults to 1. Note that `rel_id` need not be specified unless you want to model multiple different relationships between the same objects, thus keeping relationships in different 'namespaces' as it were. """ self.rm.add_rel(source, target, rel_id) def remove_rel(self, source, target, rel_id=1) -> None: """Remove all relationships between `source` and `target` of type `rel_id`. If you specify `None` for any parameter a wildcard match removal will occur. For example: Syntax | Meaning --------|------ `remove_rel('a', 'b')` | remove all relationships between 'a' and 'b' `remove_rel('a', 'b', None)` | remove all relationships between 'a' and 'b' `remove_rel('a', 'b', 'r1')` | remove the 'r1' relationship between 'a' and 'b' `remove_rel('a', None)` | remove all pointers (relationships) from 'a' `remove_rel(None, 'b')` | remove any pointers (relationships) to 'b' """ self.rm.remove_rel(source, target, rel_id) def find_targets(self, source, rel_id=1) -> List: """Find all objects pointed to by me - all the things 'source' is pointing at.""" return self.rm._find_objects(source, None, rel_id) def find_target(self, source, rel_id=1) -> object: """Find first object pointed to by me - first target""" return self.rm._find_object(source, None, rel_id) def find_sources(self, target, rel_id=1) -> List: """Find all objects pointing to me. A 'back pointer' query.""" return self.rm._find_objects(None, target, rel_id) def find_source(self, target, rel_id=1) -> object: """Find first object pointing to me - first source. A 'back pointer' query.""" return self.rm._find_object(None, target, rel_id) def is_rel(self, source, target, rel_id=1) -> bool: """Returns T/F if relationship exists.""" return self.rm._find_objects(source, target, rel_id) def find_rels(self, source, target) -> List: """Returns a list of the relationships between source and target. Returns a list of relationship ids. """ return self.rm._find_objects(source, target, None) def enforce(self, rel_id, cardinality, directionality="directional"): """Enforce a relationship by auto creating reciprocal relationships (in the case of 'bidirectional' relationships), and by overwriting existing relationships in the case of 'onetoone' cardinality. `rel_id`: the name of the relationship - either an integer or string. `cardinality`: - `"onetoone"` - extinguish both old 'source' and 'target' before adding a new relationship - `"onetomany"` - extinguish old 'source' before adding a new relationship - `"manytomany"` (not implemented) `directionality`: - `"directional"` - the default, no special enforcement - `"bidirectional"` - when calling `RelationshipManager.add_rel(source, target)` causes not only the primary relationship to be created between 'source' and 'target', but also auto creates an additional relationship in the reverse direction between 'target' and 'source'. Also ensures both relationships are removed when calling `RelationshipManager.remove_rel`. """ self.rm.enforce(rel_id, cardinality, directionality) def dumps(self) -> bytes: """Dump relationship tuples and objects to pickled bytes. The `objects` attribute and all objects stored therein (within the instance of `RelationshipManager.objects`) also get persisted. """ return pickle.dumps(_PersistenceWrapper( objects=self.objects, relationships=self.relationships)) @staticmethod def loads(asbytes: bytes): # -> RelationshipManager: """Load relationship tuples and objects from pickled bytes. Returns a `RelationshipManager` instance. """ data: _PersistenceWrapper = pickle.loads(asbytes) rm = RelationshipManager() rm.objects = data.objects rm.relationships = data.relationships return rm def clear(self) -> None: """Clear all relationships, does not affect .objects - if you want to clear that too then assign a new empty object to it. E.g. rm.objects = Namespace() """ self.rm.clear() self.objects = _Namespace() # Util def debug_print_rels(self): """Just a diagnostic method to print the relationships in the rm. See also the `RelationshipManager.relationships` property.""" print() pprint.pprint(self.relationships)
Static methods
def loads(asbytes: bytes)
-
Load relationship tuples and objects from pickled bytes. Returns a
RelationshipManager
instance.Expand source code
@staticmethod def loads(asbytes: bytes): # -> RelationshipManager: """Load relationship tuples and objects from pickled bytes. Returns a `RelationshipManager` instance. """ data: _PersistenceWrapper = pickle.loads(asbytes) rm = RelationshipManager() rm.objects = data.objects rm.relationships = data.relationships return rm
Instance variables
var objects
-
Optional place for storing objects involved in relationships, so the objects are saved. Assign to this
.objects
namespace directly to record your objects for persistence puposes. var relationships : List[Tuple[object, object, Union[int, str]]]
-
Property to get flat list of relationships tuples
Expand source code
def _get_relationships(self) -> List[Tuple[object, object, Union[int, str]]]: """Getter""" return self.rm._get_relationships()
Methods
def add_rel(self, source, target, rel_id=1) ‑> NoneType
-
Add relationships between
source
andtarget
under the optional relationship idrel_id
. Thesource
andtarget
are typically Python objects but can be strings. Therel_id
is a string or integer and defaults to 1. Note thatrel_id
need not be specified unless you want to model multiple different relationships between the same objects, thus keeping relationships in different 'namespaces' as it were.Expand source code
def add_rel(self, source, target, rel_id=1) -> None: """Add relationships between `source` and `target` under the optional relationship id `rel_id`. The `source` and `target` are typically Python objects but can be strings. The `rel_id` is a string or integer and defaults to 1. Note that `rel_id` need not be specified unless you want to model multiple different relationships between the same objects, thus keeping relationships in different 'namespaces' as it were. """ self.rm.add_rel(source, target, rel_id)
def clear(self) ‑> NoneType
-
Clear all relationships, does not affect .objects - if you want to clear that too then assign a new empty object to it. E.g. rm.objects = Namespace()
Expand source code
def clear(self) -> None: """Clear all relationships, does not affect .objects - if you want to clear that too then assign a new empty object to it. E.g. rm.objects = Namespace() """ self.rm.clear() self.objects = _Namespace()
def debug_print_rels(self)
-
Just a diagnostic method to print the relationships in the rm. See also the
RelationshipManager.relationships
property.Expand source code
def debug_print_rels(self): """Just a diagnostic method to print the relationships in the rm. See also the `RelationshipManager.relationships` property.""" print() pprint.pprint(self.relationships)
def dumps(self) ‑> bytes
-
Dump relationship tuples and objects to pickled bytes. The
objects
attribute and all objects stored therein (within the instance ofRelationshipManager.objects
) also get persisted.Expand source code
def dumps(self) -> bytes: """Dump relationship tuples and objects to pickled bytes. The `objects` attribute and all objects stored therein (within the instance of `RelationshipManager.objects`) also get persisted. """ return pickle.dumps(_PersistenceWrapper( objects=self.objects, relationships=self.relationships))
def enforce(self, rel_id, cardinality, directionality='directional')
-
Enforce a relationship by auto creating reciprocal relationships (in the case of 'bidirectional' relationships), and by overwriting existing relationships in the case of 'onetoone' cardinality.
rel_id
: the name of the relationship - either an integer or string.cardinality
:"onetoone"
- extinguish both old 'source' and 'target' before adding a new relationship"onetomany"
- extinguish old 'source' before adding a new relationship"manytomany"
(not implemented)
directionality
:"directional"
- the default, no special enforcement"bidirectional"
- when callingRelationshipManager.add_rel()(source, target)
causes not only the primary relationship to be created between 'source' and 'target', but also auto creates an additional relationship in the reverse direction between 'target' and 'source'. Also ensures both relationships are removed when callingRelationshipManager.remove_rel()
.
Expand source code
def enforce(self, rel_id, cardinality, directionality="directional"): """Enforce a relationship by auto creating reciprocal relationships (in the case of 'bidirectional' relationships), and by overwriting existing relationships in the case of 'onetoone' cardinality. `rel_id`: the name of the relationship - either an integer or string. `cardinality`: - `"onetoone"` - extinguish both old 'source' and 'target' before adding a new relationship - `"onetomany"` - extinguish old 'source' before adding a new relationship - `"manytomany"` (not implemented) `directionality`: - `"directional"` - the default, no special enforcement - `"bidirectional"` - when calling `RelationshipManager.add_rel(source, target)` causes not only the primary relationship to be created between 'source' and 'target', but also auto creates an additional relationship in the reverse direction between 'target' and 'source'. Also ensures both relationships are removed when calling `RelationshipManager.remove_rel`. """ self.rm.enforce(rel_id, cardinality, directionality)
def find_rels(self, source, target) ‑> List
-
Returns a list of the relationships between source and target. Returns a list of relationship ids.
Expand source code
def find_rels(self, source, target) -> List: """Returns a list of the relationships between source and target. Returns a list of relationship ids. """ return self.rm._find_objects(source, target, None)
def find_source(self, target, rel_id=1) ‑> object
-
Find first object pointing to me - first source. A 'back pointer' query.
Expand source code
def find_source(self, target, rel_id=1) -> object: """Find first object pointing to me - first source. A 'back pointer' query.""" return self.rm._find_object(None, target, rel_id)
def find_sources(self, target, rel_id=1) ‑> List
-
Find all objects pointing to me. A 'back pointer' query.
Expand source code
def find_sources(self, target, rel_id=1) -> List: """Find all objects pointing to me. A 'back pointer' query.""" return self.rm._find_objects(None, target, rel_id)
def find_target(self, source, rel_id=1) ‑> object
-
Find first object pointed to by me - first target
Expand source code
def find_target(self, source, rel_id=1) -> object: """Find first object pointed to by me - first target""" return self.rm._find_object(source, None, rel_id)
def find_targets(self, source, rel_id=1) ‑> List
-
Find all objects pointed to by me - all the things 'source' is pointing at.
Expand source code
def find_targets(self, source, rel_id=1) -> List: """Find all objects pointed to by me - all the things 'source' is pointing at.""" return self.rm._find_objects(source, None, rel_id)
def is_rel(self, source, target, rel_id=1) ‑> bool
-
Returns T/F if relationship exists.
Expand source code
def is_rel(self, source, target, rel_id=1) -> bool: """Returns T/F if relationship exists.""" return self.rm._find_objects(source, target, rel_id)
def remove_rel(self, source, target, rel_id=1) ‑> NoneType
-
Remove all relationships between
source
andtarget
of typerel_id
. If you specifyNone
for any parameter a wildcard match removal will occur. For example:Syntax Meaning remove_rel('a', 'b')
remove all relationships between 'a' and 'b' remove_rel('a', 'b', None)
remove all relationships between 'a' and 'b' remove_rel('a', 'b', 'r1')
remove the 'r1' relationship between 'a' and 'b' remove_rel('a', None)
remove all pointers (relationships) from 'a' remove_rel(None, 'b')
remove any pointers (relationships) to 'b' Expand source code
def remove_rel(self, source, target, rel_id=1) -> None: """Remove all relationships between `source` and `target` of type `rel_id`. If you specify `None` for any parameter a wildcard match removal will occur. For example: Syntax | Meaning --------|------ `remove_rel('a', 'b')` | remove all relationships between 'a' and 'b' `remove_rel('a', 'b', None)` | remove all relationships between 'a' and 'b' `remove_rel('a', 'b', 'r1')` | remove the 'r1' relationship between 'a' and 'b' `remove_rel('a', None)` | remove all pointers (relationships) from 'a' `remove_rel(None, 'b')` | remove any pointers (relationships) to 'b' """ self.rm.remove_rel(source, target, rel_id)