如何管理这种模式这个sqlalchemy

时间:2014-12-05 01:01:46

标签: python sqlalchemy

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

try:
    #do some database query
    db_session.commit()
except: #some exception handling
    db_session.rollback()

2 个答案:

答案 0 :(得分:2)

这是我的工作代码,一个会话注册表包装器的方法。

以这种方式使用:

# 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 SimpleSession()`
        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()

答案 1 :(得分:1)

您可以设计一个管理错误句柄的函数,您应该对它们进行评估并考虑是否需要进行性能优化。

def commit_or_rollback(my_session, do_something, error_type):
    try:
        do_something(my_session)
        my_session.commit()
        return True
    except error_type as err:
        my_session.rollback()
        print(err)
        return False

def do_something(my_session):
    # do something

commit_result = commit_or_rollback(my_session, do_something, NoResultFound)

小心会话控制和性能。这种方法可以清楚地保存代码。