Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-30-2021 11:21 AM
Hi,
I am using python to populate and drop data on neo4j with neo4j-python.
While dropping the nodes, I'm running a query like:
call apoc.periodic.iterate("MATCH (n {data_source:'APAC'})
return n", "DETACH DELETE n", {batchSize:10000})
yield batches, total return total AS count
Which is being called via this Neo4jDriver class:
class Neo4JDriver:
def __init__(self, url, user, password, encrypted=False):
self._driver = GraphDatabase.driver(url, auth=(user, password), encrypted=encrypted)
def close(self):
self._driver.close()
def exec_cypher_query(self, query):
logger.info("Firing query :: {}".format(query))
with self._driver.session() as session:
return session.run(query)
The query runs fine and does it job, but when I try to retrieve the 'count' from the Result object as in the following query:
result = exec_cypher_query(query)
But I cannot find the value of count in the result variable. I have debugged the code, and trying to follow many suggestions available in different forums, but for no success.
Earlier, I was using query:
MATCH (n {label} {props})
DETACH DELETE n
RETURN COUNT(n) as count
After which I used to get the number of deleted nodes using:
if 'stats' in result._metadata:
count = result._metadata['stats']['nodes-deleted']
Thanks. Cheers.
Solved! Go to Solution.
11-30-2021 12:58 PM
Result set objects do not outlive the session @mihaque313
The error is here:
def exec_cypher_query(self, query):
logger.info("Firing query :: {}".format(query))
with self._driver.session() as session:
return session.run(query)
The way this code works is that the "with" block creates a session, and then closes the session when you're outside of the block. So the caller of exec_cypher_query can't consume the results because they're already gone with the session.
The solution is to convert the results from the result set to some kind of object that can be used by the caller.
Here's an example:
def exec_cypher_query(self, query):
logger.info("Firing query :: {}".format(query))
with self._driver.session() as session:
r = session.run(query)
return [ dict(i) for i in r]
Notice this does not return a Neo4j result set it returns an array of results taken out of the result set, converting each one into a dictionary.
It's good practice to convert Neo4j results to some kind of native types before returning them, because this way the logic of exec_cypher_query can handle how you want to unpack those values and what schema to return and so on. If you were to return raw Neo4j results, then every caller of that function would need to know how to use the Neo4j results API
11-30-2021 12:58 PM
Result set objects do not outlive the session @mihaque313
The error is here:
def exec_cypher_query(self, query):
logger.info("Firing query :: {}".format(query))
with self._driver.session() as session:
return session.run(query)
The way this code works is that the "with" block creates a session, and then closes the session when you're outside of the block. So the caller of exec_cypher_query can't consume the results because they're already gone with the session.
The solution is to convert the results from the result set to some kind of object that can be used by the caller.
Here's an example:
def exec_cypher_query(self, query):
logger.info("Firing query :: {}".format(query))
with self._driver.session() as session:
r = session.run(query)
return [ dict(i) for i in r]
Notice this does not return a Neo4j result set it returns an array of results taken out of the result set, converting each one into a dictionary.
It's good practice to convert Neo4j results to some kind of native types before returning them, because this way the logic of exec_cypher_query can handle how you want to unpack those values and what schema to return and so on. If you were to return raw Neo4j results, then every caller of that function would need to know how to use the Neo4j results API
12-01-2021 04:45 AM
Thanks! David. Your suggestion worked!.
Didn't realize I was querying inside 'with' block.
12-01-2021 12:40 AM
An additional remark: it's not advised to rely on internal attributes starting with _
(result._metadata
in this case). It might be renamed, removed or re-purposed even in patch releases. Moreover, it's undocumented and might involve more complex behavior than it appears to. If you want to access the metadata of a query, you can use Result.consume()
which yields a ResultSummary
object that gives you access to what you need. API Documentation — Neo4j Python Driver 4.4
All the sessions of the conference are now available online