【发布时间】:2016-10-07 15:10:47
【问题描述】:
我正在使用装饰器来打开和关闭 neo4j 数据库会话(并允许我的装饰函数在该会话中运行查询)。起初我使用了一个装饰器功能:
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
然后我调用这个函数:
@session
def RUN(command,session):
result=session.run(command)
return(result)
但是,这会为每个消耗资源的查询打开和关闭会话。因此,我尝试创建一个装饰器类,并存储会话:
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")
这似乎有效,因为“会话已打开”只出现一次。但会话似乎没有关闭(“会话关闭”从未打印出来)。
所以我的第一个问题如下,我如何在装饰器销毁时调用 self.SESSION.close() ?
我也想知道我是否很好地理解了我的代码在做什么。当我调用RUN 之类的修饰函数时,是否只创建了一个会话对象?如果我有另一个装饰函数MATCH
@session
def MATCH(*args,**kwargs):
pass
会话对象是否相同?
【问题讨论】:
-
当它装饰的所有函数消失时,该类可能会消失(在这种情况下,看起来每个装饰的函数都有一个会话)。如果函数处于模块级别,则答案是在解释器关闭之前会话不会关闭(并且可能甚至不会关闭)。
标签: python database-connection decorator python-decorators