处理sqlalchemy断开连接的更好方法

use*_*028 19 python postgresql sqlalchemy

我们一直在尝试sqlalchemy的断开处理,以及它如何与ORM集成.我们研究了文档,建议似乎是捕获断开连接异常,发出rollback()并重试代码.

例如:

import sqlalchemy as SA

retry = 2
while retry:
    retry -= 1
    try:
        for name in session.query(Names):
            print name
        break
    except SA.exc.DBAPIError as exc:
        if retry and exc.connection_invalidated:
            session.rollback()
        else:
            raise
Run Code Online (Sandbox Code Playgroud)

我遵循基本原理 - 您必须回滚任何活动的事务并重放它们以确保您的操作的一致排序.

但是 - 这意味着每个想要处理数据的函数都会添加许多额外的代码.此外,在这种情况下SELECT,我们不修改数据,回滚/重新请求的概念不仅难看,而且违反DRY原则(不要重复自己).

我想知道其他人是否会介意分享他们如何处理与sqlalchemy的断开连接.

仅供参考:我们使用的是sqlalchemy 0.9.8和Postgres 9.2.9

Mar*_*cny 9

我喜欢这样做的方法是将我的所有数据库代码放在lambda或闭包中,并将其传递给一个帮助函数,该函数将处理捕获断开连接异常并重试.

以你的例子为例:

import sqlalchemy as SA

def main():
    def query():
        for name in session.query(Names):
            print name

    run_query(query)

def run_query(f, attempts=2):
    while attempts > 0:
        attempts -= 1
        try:
            return f() # "break" if query was successful and return any results
         except SA.exc.DBAPIError as exc:
            if attempts > 0 and exc.connection_invalidated:
                session.rollback()
            else:
                raise
Run Code Online (Sandbox Code Playgroud)

你可以通过传入一个布尔值run_query来处理你只进行读取的情况,因此想要在不回滚的情况下重试.

这有助于您满足DRY原则,因为用于管理重试和回滚的所有丑陋的样板代码都放在一个位置.