在阅读官方SQLAlchemy文档时,我找到了以下示例:
### this is the **wrong way to do it** ###
class ThingOne(object):
def go(self):
session = Session()
try:
session.query(FooBar).update({"x": 5})
session.commit()
except:
session.rollback()
raise
class ThingTwo(object):
def go(self):
session = Session()
try:
session.query(Widget).update({"q": 18})
session.commit()
except:
session.rollback()
raise
def run_my_program():
ThingOne().go()
ThingTwo().go()
我真的不明白这种模式的缺点。实际上我可以想到一个主要的优点:在多线程上下文中,这种模式可以确保每个会话实例都是实际使用它的函数的局部变量。
有人可以通过给出上面例子的一些潜在缺点来启发我吗?感谢。
编辑:作为多线程上下文优势的示例。如果我们在这里有一个Web应用程序服务器类:
class WebApp:
def update(self, **kwargs):
session = Session()
try:...
这里,页面处理程序update
有自己的局部变量session
,因此无论它运行多少线程,它总是安全的。相反,使用另一个函数层来包含session
会在这种情况下引入更复杂的方法
答案 0 :(得分:-1)
简单来说,sqlalchemy建议会话的处理不要与数据的操作混合在一起。正如您在下一个示例中所看到的那样。
### this is a **better** (but not the only) way to do it ###
class ThingOne(object):
def go(self, session):
session.query(FooBar).update({"x": 5})
class ThingTwo(object):
def go(self, session):
session.query(Widget).update({"q": 18})
def run_my_program():
session = Session()
try:
ThingOne().go(session)
ThingTwo().go(session)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
ThingOne和ThingTwo正在做CRUD,但会话的处理是在这些对象之外完成的。
对于多线程,会话范围是线程本地对象。意思是,它们不能被不同的线程共享。您可以将它们声明为您指定的内容,但这并不意味着从外部实体处理会话也是不好的选择。