cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Show db hits for query using Python Driver

pska752
Node Link

Hi Neo4j Community,

Thank you very much for always being so helpful. I am just getting starting with Python Driver and I would like to meassure the performance of the queries I execute.

For this I would like to know the total db hits for the queries I am executing just like in Neo4j directly using PROFILE.

I have read through various posts and searched and read through manuals and documentations and feel like I am close, but not quite there.

My python code looks as follows

and I get the output

which has all the relevant db hits in there. I am just wondering if there is a nicer way to get the total and trying to access this information from ......consume().profile could this not be different again for a different query and I would first have to look through the result and see how to access the single db hits information and add them up.

Just wondering if there is an easy way to access the 37 db hits (in this example) in an easier way?

Thank you very much for your help.

Best,
Philipp

4 REPLIES 4

Hi Philipp,

currently, there is no convenience function to sum up all db hits for you. And the profile being this tree structure is just what the driver gets from the DBMS. However, you can write a little function that does it for you. It could look something like this:

def sum_db_hits(profile):
    return (profile.get("dbHits", 0)
            + sum(map(sum_db_hits, profile.get("children", []))))

In context:

import neo4j


def profile_query(tx, query, **params):
    # make sure the DBMS gives us a profile back.
    query_lower = query.strip().lower()
    if not (query_lower.startswith("profile")
            or query_lower.startswith("explain")):
        query = "PROFILE " + query
    result = tx.run(query, params)
    return result.consume().profile


def sum_db_hits(profile):
    return (profile.get("dbHits", 0)
            + sum(map(sum_db_hits, profile.get("children", []))))


def main():
    auth = ('neo4j', 'pass')
    uri = 'neo4j://localhost:7687'
    with neo4j.GraphDatabase.driver(uri, auth=auth) as driver:
        with driver.session() as session:
            profile = session.read_transaction(
                profile_query,
                "<YOUR QUERY HERE>"
            )
            print(sum_db_hits(profile))


if __name__ == "__main__":
    main()

Hi Rouven,

Thank you back then for helping me with getting the db hits using Python.

I have not touched my code in a while, but now things don't seem to work anymore.

I got the following snippet

 

def show_dbhits(database, query):

    
    new_db = database
    
    result = new_db.execute_query_with_output(query)


    summary = result.consume().profile


    return  sum_db_hits(summary)


# getting db_hits

def sum_db_hits(profile):
    return (profile.get("dbHits", 0) + sum(map(sum_db_hits, profile.get("children", []))))

 and suddenly get as error message that NoneType object has no attribute .get

I printed result and printed summary after the respective lines to see what kind of object they are and get the following:

 

<neo4j.work.result.Result object at 0x000001ED2F7FC520>

None

 

Has anything changed due to some updates and do I now have to go differently about it? I tried a couple of things and looked online, but could not come up with a solution.

 

Thanks a lot for any help.

Hi,

I figured it out. The reason why .profile in line 9 returned a None-type object was because the query I executed didn't contain "PROFILE".

 

Silly mistake 🙂

pska752
Node Link

Hi Rouven,

Thank you very much for the detailed answer, much appreciated.

Good to know that this workaround is the best solution at this moment and I will make sure to use it.

Best,
Philipp