Search code examples
pythonneo4jpy2neoneomodel

Neo4j, py2neo, Neomodel - Cypher Shortest Path giving error - TypeError: 'NotImplementedType' object is not callable


I'm trying to run the following Cypher query in neomodel:

MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }), 
p = shortestPath((b1)-[*..15]-(b2)) 
RETURN p

which works great on neo4j via the server console. It returns 3 nodes with two relationships connecting. However, when I attempt the following in python:

# Py2Neo version of cypher query in python
from py2neo import neo4j
graph_db = neo4j.GraphDatabaseService()
shortest_path_text = "MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }), p = shortestPath((b1)-[*..15]-(b2)) RETURN p"
results = neo4j.CypherQuery(graph_db, shortest_path_text).execute()

or

# neomodel version of cypher query in python
from neomodel import db
shortest_path_text = "MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }), p = shortestPath((b1)-[*..15]-(b2)) RETURN p"
results, meta = db.cypher_query(shortest_path_text)

both give the following error:

     /Library/Python/2.7/site-packages/neomodel-1.0.1-py2.7.egg/neomodel/util.py in _hydrated(data)
     73             elif obj_type == 'relationship':
     74                 return Rel(data)
---> 75         raise NotImplemented("Don't know how to inflate: " + repr(data))
     76     elif neo4j.is_collection(data):
     77         return type(data)([_hydrated(datum) for datum in data])

TypeError: 'NotImplementedType' object is not callable

which makes sense considering neomodel is based on py2neo.

The main question is how to get a shortestPath query to work via either of these? Is there a better method within python? or is cypher the best way to do it?

edit:
I also tried the following from here which gave the same error.

graph_db = neo4j.GraphDatabaseService()
    query_string = "START beginning=node(1), end=node(4) \
                MATCH p = shortestPath(beginning-[*..500]-end) \
                RETURN p"

    result = neo4j.CypherQuery(graph_db, query_string).execute()

    for r in result:
        print type(r) # r is a py2neo.util.Record object
        print type(r.p) # p is a py2neo.neo4j.Path object

Solution

  • Ok, I figured it out. I used the tutorial [here]( based on @nigel-small 's answer.

    from py2neo import cypher
    
    session = cypher.Session("http://localhost:7474")
    tx = session.create_transaction()
    
    tx.append("START beginning=node(3), end=node(16) MATCH p = shortestPath(beginning-[*..500]-end) RETURN p")
    tx.execute()
    

    which returned:

    [[Record(columns=(u'p',), values=(Path(Node('http://localhost:7474/db/data/node/3'), ('threads', {}), Node('http://localhost:7474/db/data/node/1'), ('threads', {}), Node('http://localhost:7474/db/data/node/2'), ('threads', {}), Node('http://localhost:7474/db/data/node/16')),))]]
    

    From here, I expect I'll inflate each of the values back to my neomodel objects and into django for easier manipulation. Will post that code as I get there.