versae / neo4j-rest-client

Object-oriented Python library to interact with Neo4j standalone REST server
http://neo4j-rest-client.rtfd.org
GNU General Public License v3.0
264 stars 73 forks source link

Question: How do I cast optional nodes? #132

Open g3rd opened 7 years ago

g3rd commented 7 years ago

Query:

MATCH (person:Person {id: 1})
OPTIONAL MATCH (person)-[:OWNS]->(product:Product)
RETURN person, product

Execute Query

with graph.transaction(commit=False) as tx:
    results = graph.query(q, returns=(client.Node, client.Node, ))

Exception

If I execute the Query and it has the optional match, no exception. If the optional match returns None I get:

  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 829, in __exit__
    self.commit()
  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 948, in commit
    results = self._execute(url, results=True)
  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 868, in _execute
    _results = self._update(content["results"])
  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 891, in _update
    obj, elements=result["data"], returns=returns
  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 792, in cast
    casted_row.append(cast_element(element, func))
  File "/usr/local/lib/python3.5/site-packages/neo4jrestclient/query.py", line 714, in cast_element
    obj = func(element["self"], update_dict=element,
TypeError: 'NoneType' object is not subscriptable
g3rd commented 7 years ago

Updated the Execute Query section to include the transaction.

versae commented 7 years ago

It looks like I should check whether element is None before getting element["self"]. In the meantime you could try casting to neo4jrestclient.constants.RAW:

with graph.transaction(commit=False) as tx:
    results = graph.query(q, returns=(RAW, client.Node, ))

Or even create your own casting function:

with graph.transaction(commit=False) as tx:
    results = graph.query(q,
        returns=(lambda x: graph.node(x["self"]) if x and "self" in x else None,
                 client.Node, ))

Let me know if any of this approaches work.