def test_can_push_path(graph): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) graph.create(path) if graph.neo4j_version >= (2, 0, 0): query = """\ START ab=rel({ab}), bc=rel({bc}), cd=rel({cd}) RETURN ab.amount, bc.amount, cd.since """ else: query = """\ START ab=rel({ab}), bc=rel({bc}), cd=rel({cd}) RETURN ab.amount?, bc.amount?, cd.since? """ params = {"ab": path[0]._id, "bc": path[1]._id, "cd": path[2]._id} path[0].properties["amount"] = "lots" path[1].properties["amount"] = "some" path[2].properties["since"] = 1999 results = graph.cypher.execute(query, params) ab_amount, bc_amount, cd_since = results[0].values assert ab_amount is None assert bc_amount is None assert cd_since is None path.push() results = graph.cypher.execute(query, params) ab_amount, bc_amount, cd_since = results[0].values assert ab_amount == "lots" assert bc_amount == "some" assert cd_since == 1999
def test_can_push_path(graph): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) graph.create(path) if graph.neo4j_version >= (2, 0, 0): query = """\ START ab=rel({ab}), bc=rel({bc}), cd=rel({cd}) RETURN ab.amount, bc.amount, cd.since """ else: query = """\ START ab=rel({ab}), bc=rel({bc}), cd=rel({cd}) RETURN ab.amount?, bc.amount?, cd.since? """ params = {"ab": path[0]._id, "bc": path[1]._id, "cd": path[2]._id} path[0].properties["amount"] = "lots" path[1].properties["amount"] = "some" path[2].properties["since"] = 1999 results = graph.cypher.execute(query, params) ab_amount, bc_amount, cd_since = results[0] assert ab_amount is None assert bc_amount is None assert cd_since is None path.push() results = graph.cypher.execute(query, params) ab_amount, bc_amount, cd_since = results[0] assert ab_amount == "lots" assert bc_amount == "some" assert cd_since == 1999
def test_can_unbind_unbound_path_without_error(): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) path.unbind() assert not path.bound
def test_can_unbind_bound_path(graph): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) graph.create(path) path.unbind() assert not path.bound
def __init__(self, *entities): # Fudge to allow graph to be passed in so Cypher syntax # detection can occur. Can be removed when only 2.0+ is # supported. if isinstance(entities[0], Graph): self.graph, entities = entities[0], entities[1:] CypherJob.__init__(self, *_create_query(self.graph, Path(*entities)))
def test_unbound_path_is_not_bound(): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) assert not path.bound
def test_cannot_create_unique_zero_length_path(graph): path = Path(Node()) statement = CreateStatement(graph) try: statement.create_unique(path) except ValueError: assert True else: assert False
def test_can_pull_path(graph): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) graph.create(path) assert path[0].properties["amount"] is None assert path[1].properties["amount"] is None assert path[2].properties["since"] is None assert path[0].rel.properties["amount"] is None assert path[1].rel.properties["amount"] is None assert path[2].rel.properties["since"] is None graph.cypher.run("""\ START ab=rel({ab}), bc=rel({bc}), cd=rel({cd}) SET ab.amount = "lots", bc.amount = "some", cd.since = 1999 """, {"ab": path[0]._id, "bc": path[1]._id, "cd": path[2]._id}) path.pull() assert path[0].properties["amount"] == "lots" assert path[1].properties["amount"] == "some" assert path[2].properties["since"] == 1999 assert path[0].rel.properties["amount"] == "lots" assert path[1].rel.properties["amount"] == "some" assert path[2].rel.properties["since"] == 1999
def hydrate(self, data): """ Hydrate a dictionary of data to produce a :class:`.Node`, :class:`.Relationship` or other graph object instance. The data structure and values expected are those produced by the `REST API <http://neo4j.com/docs/stable/rest-api.html>`__. :arg data: dictionary of data to hydrate """ if isinstance(data, dict): if "self" in data: if "type" in data: return Relationship.hydrate(data) else: return Node._find_hydrator(data) elif "nodes" in data and "relationships" in data: if "directions" not in data: from py2neo.batch import Job, Target node_uris = data["nodes"] relationship_uris = data["relationships"] jobs = [Job("GET", Target(uri)) for uri in relationship_uris] directions = [] for i, result in enumerate(self.batch.submit(jobs)): rel_data = result.content start = rel_data["start"] end = rel_data["end"] if start == node_uris[i] and end == node_uris[i + 1]: directions.append("->") else: directions.append("<-") data["directions"] = directions return Path.hydrate(data) elif "columns" in data and "data" in data: from py2neo.cypher import RecordList return RecordList.hydrate(data, self) elif "neo4j_version" in data: return self elif "exception" in data and ("stacktrace" in data or "stackTrace" in data): message = data.pop("message", "The server returned an error") raise GraphError(message, **data) else: warn("Map literals returned over the Neo4j REST interface are ambiguous " "and may be hydrated as graph objects") return data elif is_collection(data): return type(data)(map(self.hydrate, data)) else: return data
def test_can_create_a_path_with_existing_nodes(graph): alice = graph.cypher.execute_one("CREATE (a {name:'Alice'}) RETURN a") bob = Node(name="Bob") carol = graph.cypher.execute_one("CREATE (c {name:'Carol'}) RETURN c") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) statement = CreateStatement(graph) statement.create(path) created = statement.execute() assert created == (path, ) assert bob.bound assert dave.bound ab, cb, cd = path.relationships assert ab.start_node is alice assert ab.end_node is bob assert cb.start_node is carol assert cb.end_node is bob assert cd.start_node is carol assert cd.end_node is dave
def test_can_create_an_entirely_new_path(graph): alice = Node(name="Alice") bob = Node(name="Bob") carol = Node(name="Carol") dave = Node(name="Dave") path = Path(alice, "LOVES", bob, Rev("HATES"), carol, "KNOWS", dave) statement = CreateStatement(graph) statement.create(path) created = statement.execute() assert created == (path, ) assert alice.bound assert bob.bound assert carol.bound assert dave.bound ab, cb, cd = path.relationships assert ab.start_node is alice assert ab.end_node is bob assert cb.start_node is carol assert cb.end_node is bob assert cd.start_node is carol assert cd.end_node is dave
def _node_create_path(self, *items): path = Path(self, *items) return _path_create(path, self.graph)
def __init__(self, *entities): CypherJob.__init__(self, *_create_query(Path(*entities), unique=True))
def __init__(self, *entities): CypherJob.__init__(self, *_create_query(Path(*entities)))
def test_can_write_simple_path(): r = Representation() r.write(Path({}, "LOVES", {}, Rev("HATES"), {}, "KNOWS", {})) written = repr(r) assert written == "()-[:LOVES]->()<-[:HATES]-()-[:KNOWS]->()"