I am using a decorator to open and close a neo4j database session (and allow my decorated functions to run queries within that session). At first I used a decorator function :
from neo4j.v1 import GraphDatabase, basic_auth
def session(func,url="bolt://localhost:7474", user="neo4j",pwd="neo4j", *args, **kwargs):
def operate(*args, **kwargs):
driver = GraphDatabase.driver(url, auth=basic_auth(user,pwd))
session=driver.session()
kwargs["session"]=session
result=func(*args, **kwargs)
session.close()
return result
return operate
and for example I then call this function:
@session
def RUN(command,session):
result=session.run(command)
return(result)
However, this opens and closes the session for every query which is resource consuming. Thus, I tried to create a decorator class, and store the session:
class session(object):
def __init__(self, func, url="bolt://localhost", user="neo4j", pwd="neo4j"):
try:
driver = GraphDatabase.driver(url, auth=basic_auth(user, pwd))
print("session opened")
except:
print("Exception during authentification")
self.__exit__()
else:
session=driver.session()
self.func=func
self.SESSION=session
def __call__(self, *args, **kwargs):
kwargs["session"]=self.SESSION
result=self.func(*args, **kwargs)
return result
def __del__(self):
print("del")
try:
self.SESSION.close()
print("session closed")
except:
print("could not close session")
This seems to work, as the "session opened" appears only once. But the session does not seem to close ("session close" is never printed).
So my first question is the following, how can I call the self.SESSION.close() at the destruction of the decorator ?
I'm also wondering if I understood well what my code is doing. When I call a decorated function such as RUN
, is only one session object created? And what if I were to have an other decorated function MATCH
@session
def MATCH(*args,**kwargs):
pass
would the session object be the same ?