2017-08-07 39 views
0

当读正式SQLAlchemy的文档,我发现下面的例子:为什么在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

你为什么不引用[文档中提出的更好的解决方案以及给出的原因](http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i -construct-A-会话时-DO-提交 - 它和当-DO-近距它)。 –

+0

@IljaEverilä我没有引用'Do'的例子,因为它只显示了一个完全相反的解决方案。所以我认为引用一方会足以说明这个问题。即使引用了它,它仍然不清楚它给你带来的好处。这只是一个抽象的原则来区分顾虑。但在我的情况下,我需要它绝对是线程安全的,最好不会引入另一层复杂性。 –

+0

@IljaEverilä为什么downvote我的问题?我试图阐明一个不同的观点。这不是对我们的知识库做出的贡献,以便更好地理解该做什么和不该做什么吗? –

回答

-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,但会议的处理是那些对象之外完成。

对于多线程,会话作用域是线程本地对象。意思是说,他们不能被不同的线程共享。您可以将它们声明为您指定的内容,但这并不意味着从外部实体处理会话也是不好的选择。

+0

“会话范围”是指[范围会话](http://docs.sqlalchemy.org/en/latest/orm/contextual.html)吗?措辞很重要,因为“会话范围”意味着所有会话都具有线程本地范围,而不是这样。 –

相关问题