简体   繁体   中英

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

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.

The error message you provide is specific to neomodel and looks to have been raised as there is not yet any support for inflating py2neo Path objects in neomodel.

This should however work fine in raw py2neo as paths are fully supported, so it may be worth trying that again. Py2neo certainly wouldn't raise an error from within the neomodel code. I've just tried a shortestPath query myself and it returns a value as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM