def __init__(self, graph): self.graph = graph if self.graph.supports_optional_match: self.__delete_query = ( StartOrMatch(self.graph).node("a", "{A}").string + "OPTIONAL MATCH a-[r]-b " "DELETE r, a") else: self.__delete_query = ( StartOrMatch(self.graph).node("a", "{A}").string + "MATCH a-[r?]-b " "DELETE r, a")
def save(self, subj, node=None): """ Save an object to a database node. :param subj: the object to save :param node: the database node to save to (if omitted, will re-save to same node as previous save) """ if node is not None: subj.__node__ = node # naively copy properties from object to node props = {} for key, value in subj.__dict__.items(): if not key.startswith("_"): props[key] = value if hasattr(subj, "__node__"): subj.__node__.set_properties(props) self.graph.cypher.run( StartOrMatch(self.graph).node("a", "{a}").string + "MATCH (a)-[r]->(b) DELETE r", {"a": subj.__node__}) else: subj.__node__, = self.graph.create(props) # write rels if hasattr(subj, "__rel__"): batch = WriteBatch(self.graph) for rel_type, rels in subj.__rel__.items(): for rel_props, endpoint in rels: end_node = self._get_node(endpoint) if end_node not in self.graph: raise ValueError(end_node) batch.create( (subj.__node__, rel_type, end_node, rel_props)) batch.run() return subj
def __init__(self, graph): self.graph = graph self.supports_node_labels = self.graph.supports_node_labels self.entities = [] self.start_or_match_clause = StartOrMatch(self.graph) self.delete_rels_clause = [] self.delete_nodes_clause = [] self.parameters = {}
def __init__(self, graph): self.graph = graph self.supports_node_labels = self.graph.supports_node_labels self.entities = [] self.names = [] self.start_or_match_clause = StartOrMatch(self.graph) self.create_clause = [] self.create_unique_clause = [] self.return_clause = [] self.parameters = {}
def _node_delete_related(self): from py2neo.cypher.util import StartOrMatch graph = self.graph foreach_symbol = "|" if graph.supports_foreach_pipe else ":" statement = ( StartOrMatch(graph).node("a", "{a}").string + "MATCH (a)-[rels*0..]-(z) " "FOREACH(r IN rels %s DELETE r) " "DELETE a, z" % foreach_symbol ) graph.cypher.post(statement, {"a": self._id})
def _relationship_update_properties(self, properties): if self.bound: from py2neo.cypher.lang import cypher_escape from py2neo.cypher.util import StartOrMatch graph = self.graph query, params = [StartOrMatch(graph).node("a", "{A}").string], {"A": self._id} for i, (key, value) in enumerate(properties.items()): value_tag = "V" + str(i) query.append("SET a.%s={" + value_tag + "}" % cypher_escape(key)) params[value_tag] = value query.append("RETURN a") rel = graph.cypher.execute_one("\n".join(query), params) self._properties = rel.__metadata__["data"] else: self._properties.update(properties)
def _path__create_query(self, graph, unique): from py2neo.cypher.util import StartOrMatch start_or_match_clause = StartOrMatch(graph) path, values, params = [], [], {} def append_node(i, node): if node is None: path.append("(n{0})".format(i)) values.append("n{0}".format(i)) elif node.bound: path.append("(n{0})".format(i)) start_or_match_clause.node("n%s" % i, "{i%s}" % i) params["i{0}".format(i)] = node._id values.append("n{0}".format(i)) else: path.append("(n{0} {{p{0}}})".format(i)) params["p{0}".format(i)] = node.properties values.append("n{0}".format(i)) def append_rel(i, rel): if rel.properties: path.append("-[r{0}:`{1}` {{q{0}}}]->".format(i, rel.type)) params["q{0}".format(i)] = rel.properties values.append("r{0}".format(i)) else: path.append("-[r{0}:`{1}`]->".format(i, rel.type)) values.append("r{0}".format(i)) append_node(0, self._Path__nodes[0]) for i, rel in enumerate(self._Path__rels): append_rel(i, rel) append_node(i + 1, self._Path__nodes[i + 1]) clauses = [] if len(start_or_match_clause) > 0: clauses.append(start_or_match_clause.string) if unique: clauses.append("CREATE UNIQUE p={0}".format("".join(path))) else: clauses.append("CREATE p={0}".format("".join(path))) clauses.append("RETURN p") query = "\n".join(clauses) return query, params
def _create_query(graph, p, unique=False): start_or_match_clause = StartOrMatch(graph) path, values, params = [], [], {} def append_node(i, node): if node is None: path.append("(n{0})".format(i)) values.append("n{0}".format(i)) elif node.bound: path.append("(n{0})".format(i)) start_or_match_clause.node("n%s" % i, "{i%s}" % i) params["i{0}".format(i)] = node._id values.append("n{0}".format(i)) else: path.append("(n{0} {{p{0}}})".format(i)) params["p{0}".format(i)] = node.properties values.append("n{0}".format(i)) def append_rel(i, rel): if rel.properties: path.append("-[r{0}:`{1}` {{q{0}}}]->".format(i, rel.type)) params["q{0}".format(i)] = PropertySet(rel.properties) values.append("r{0}".format(i)) else: path.append("-[r{0}:`{1}`]->".format(i, rel.type)) values.append("r{0}".format(i)) append_node(0, p.nodes[0]) for i, rel in enumerate(p.rels): append_rel(i, rel) append_node(i + 1, p.nodes[i + 1]) clauses = [] if start_or_match_clause: clauses.append(start_or_match_clause.string) if unique: clauses.append("CREATE UNIQUE p={0}".format("".join(path))) else: clauses.append("CREATE p={0}".format("".join(path))) clauses.append("RETURN p") query = "\n".join(clauses) return query, params
def refresh(self): from py2neo.cypher.util import StartOrMatch graph = self.graph statement = StartOrMatch(graph).node("a", "{a}").string + "RETURN a" graph.cypher.execute(statement, {"a": self}) self._Node__stale.clear()
def _node_isolate(self): from py2neo.cypher.util import StartOrMatch graph = self.graph query = StartOrMatch(graph).node("a", "{a}").string + "MATCH a-[r]-b DELETE r" graph.cypher.post(query, {"a": self._id})