如何更好地处理Flask-SQLAlchemy提交/回滚?

时间:2017-09-13 19:46:06

标签: python sqlalchemy

我正在查看我编写的一些旧代码,并且正在查看我编写的一个共享提交函数,用于在尝试提交对数据库的更改(例如删除)时处理对某些失败的用户响应:

def _commit_to_database():
    """A shared function to make a commit to the database and handle exceptions
    if encountered.
    """
    flask.current_app.logger.info('Committing changes to database...')
    try:
        db.session.commit()
    except AssertionError as err:
        flask.abort(409, err)
    except (exc.IntegrityError, sqlite3.IntegrityError) as err:
        flask.abort(409, err.orig)
    except Exception as err:
        flask.abort(500, err)
    finally:
        db.session.rollback()

我想我理解我的思考过程:尝试commit,在某些失败时触发flask.abort发送回复,但我相信我发现数据库留下了一个开放的会话需要当我执行此操作并将rollback添加到finally语句中时回滚,这样我就可以继续使用flask.abort

我身边的问题代码是:

1)这是一个错误:Flask-SQLAlchemy扩展会不会正常关闭会话;正在调用rollback上的finallyabort会在commit影响成功try-except-finally后触发?

2)如果这是一个错误:在处理dbpublic void calculateRoute(GeoCoordinate start, GeoCoordinate end, final RouteListener listener) { RoutePlan routePlan = new RoutePlan(); RouteOptions routeOptions = new RouteOptions(); routeOptions.setTransportMode(RouteOptions.TransportMode.CAR); routeOptions.setRouteType(RouteOptions.Type.SHORTEST); routeOptions.setRouteCount(1); routePlan.setRouteOptions(routeOptions); RouteManager routeManager = new RouteManager(); routePlan.addWaypoint(start); routePlan.addWaypoint(end); routeManager.calculateRoute(routePlan, new RouteManager.Listener() { @Override public void onCalculateRouteFinished(RouteManager.Error error, List<RouteResult> list) { if(error == RouteManager.Error.NONE) { if(list.get(0).getRoute() != null) { MapRoute mapRoute = new MapRoute(list.get(0).getRoute()); listener.gotRoute(mapRoute); } else { listener.gotRoute(null); } } else { listener.gotRoute(null); } } @Override public void onProgress(int i) {} }); } 会话时,我应该做些什么?

1 个答案:

答案 0 :(得分:1)

您需要在发生异常时回滚并最终关闭会话:

def _commit_to_database(): 
    """A shared function to make a   
       commit to the database and
       handle exceptions if encountered.
    """
    flask.current_app.logger.info(
        'Committing changes to db...'
    )
    try: 
        db.session.commit() 
    except AssertionError as err:
        db.session.rollback()
        flask.abort(409, err) 
    except (
        exc.IntegrityError, 
        sqlite3.IntegrityError
     ) as err:
        db.session.rollback()
        flask.abort(409, err.orig) 
    except Exception as err:
        db.session.rollback()
        flask.abort(500, err) 
    finally: 
        db.session.close()