I'm going through the how-to-guide on gqlalchemy
and I don't see a way to get all the connected nodes of a starting node. I tried supplying only _start_node_id
, but I get GQLAlchemyError: Can't load a relationship without a start_node_id and end_node_id
. Here’s part fo my code:
john = UserNode(id="1", username="John").save(db)
lang1 = Language(name="en").save(db)
lang2 = Language(name="fr").save(db)
# want all languages which john speaks
Speaks(_start_node_id=john._id).load(db)
# GQLAlchemyError: Can't load a relationship without a start_node_id and end_node_id
A partial loading is currently not supported when using an OGM. You can try this workaround:
class Nodes:
"""
mimic neomodel's SomeNode.nodes.all(), SomeNode.nodes.get_or_none
"""
def init(self, node_class):
self.node_class = node_class
def all(self):
root_label = self.node_class.__name__
q = f'MATCH (n:{root_label}) RETURN n'
res = db.execute_and_fetch(query=q)
lst = list(map(lambda ob: ob['n'], res))
return lst
def get_or_none(self, uid: str):
q = f'MATCH (n {{uid : "{uid}" }}) RETURN n'
res = db.execute_and_fetch(query=q)
lst = list(map(lambda ob: ob['n'], res))
out = lst[0] if len(lst) else None
return out
class NodeAPI(Node):
"""
- neomodel's obj.save(), obj.nodes.all(), obj.get_or_none(),
- my own materialize function, which overwrites the key with actual data
"""
def save(self):
return db.save_node(self)
@classmethod
def nodes(cls):
return Nodes(cls)
def materialize(self, base_class=None):
kw = {}
for key, _ in self.__fields__.items():
kw[key] = getattr(self, key)
import inspect
if base_class is None:
immediate_parent_class = inspect.getmro(self.__class__)[1]
return immediate_parent_class(**kw)
else:
return base_class(**kw)
def __str__(self):
kw = {}
for key, _ in self.__fields__.items():
kw[key] = getattr(self, key)
return f'<{type(self).__name__}, {str(kw)}>'