如何在sqlalchemy中管理此提交/回退模式

发布于 2021-01-29 15:00:22

我发现自己在sqlalchemy中重复了很多这样的事情,我想知道处理它的最佳方法是什么?

try:
    #do some database query
    db_session.commit()
except: #some exception handling
    db_session.rollback()
关注者
0
被浏览
105
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    从我的工作代码(会话注册表包装器的一种方法)来看,这是正确的。

    它是这样使用的:

    # dblink is an object that knows how to connect to the database
    with dblink.CommittingSession() as session:
      session.add(...)
      # do anything else.
    # at this point, session.commit() has been called.
    

    要么:

    try:
      with dblink.CommittingSession() as session:
        session.add(...)
    except ...:
      # at this point, session.rollback has been called.
      log.error('We failed!')
    

    实现:

    from contextlib import contextmanager
    
    class DbLink(object):
        """This class knows how to connect to the database."""
        # ...
        # Basically we wrap a sqlalchemy.orm.sessionmaker value here, in session_registry.
        # You might want to create sessions differently.
    
        @contextmanager
        def CommittingSession(self, **kwargs):
          """Creates a session, commits at the end, rolls back on exception, removes.
    
          Args:
            **kwargs: optional; supplied to session_registry while asking
              to construct a session (mostly for testing).
    
          Yields:
            a session object. The session will .commit() when a `with CommittingSession()`
            statement terminates normally, or .rollback() on an exception.
          """
          try:
            session = self.session_registry(**kwargs)  # this gives us a session.
            # transaction has already begun here, so no explicit .begin().
            yield session
          except:
            session.rollback()
            raise
          else:
            session.commit()
          finally:
            # Note: close() unbinds model objects, but keeps the DB connection.
            session.close()
            self.session_registry.remove()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看