Hola lista. Me contesto a mi mismo, por si alguien se encuentra con este mismo asunto.
El tema no está tanto en la sesión de SQLAlchemy, sino en el manejo de las transacciones que hace Pyramid (tal como queda configurado usando su cookiecutter recomendado para hacer un proyecto básico [1]) En estas circunstancias las transacciones las maneja el módulo transaction[2] tal como lo configura pyramid_tm[3] y leyendo este código fuente he podido hacerme una idea de como tratar la situación: Usando request.tm.doom() en lugar de request.dbsession.rollback() he conseguido que las cosas funcionen como quería (eso creo). Saludos Miguel Sánchez [1] https://github.com/Pylons/pyramid-cookiecutter-starter [2] https://github.com/zopefoundation/transaction [3] https://github.com/Pylons/pyramid_tm/blob/master/src/pyramid_tm/__init__.py El Sun, 9 Oct 2022 12:50:56 +0100 Miguel Sanchez <msanc...@uninet.edu> dijo: > Hola Lista. > > Estoy comenzando con Pyramid + SQLAlchemy y me he atascado. > > Es posible que esté haciendo varias cosas mal al mismo tiempo. Les digo cómo > lo estoy haciendo: > > He definido los modelos, según la documentación recomienda (creo): > > class Mitabla(Base): > __tablename__ = 'mitabla' > id = Column(Integer, primary_key=True) > dato1 = Column(Integer) > > def __init__(self, dato1): > self.dato1 = dato1 > > def __setattr__(self, attr, valor): > if attr == 'dato1': > if not isinstance(int(valor), int): > raise ValueError('dato1 no es un int') > super().__setattr__(attr, valor) > > > Como pueden ver uso __setattr__ para filtrar los valores que se pueden > asignar a las columnas. > > He definido una "vista" que va a ser invocada desde un ajax y que espero me > devuelva unos valores json: > > @view_config(route_name='haceralgo', > http_cache=0, > renderer='json' > ) > def haceralgo(request): > > En dicha vista tengo varios executes a la sesion del request > (request.dbsession) > Unos seleccionan datos, otras borran, otras actualizan > > Esto funciona perfectamente, genero una respuesta json y los datos quedan > modificados/borrados > > try: > sentencia = select( .... > resultado = request.dbsession.execute(sentencia).scalar_one() > sentencia = delete( .... > request.dbsession.execute(sentencia) > sentencia = select( ... > resultado2 = request.dbsession.execute(sentencia).scalar_one() > resultado2.dato1 = 100 > > return Response(..... > except .... > > El problema aparece cuando hay un error y quiero capturarlo .... por ejemplo > haciendo que resultado2.dato1 = 'No sea un entero' o simplemente metiendo un > 1/0 en el try ... except > > Mi idea es capturar el error, loguearlo y enviar un json informando del error > > Si hago: > except Exception as error: > request.dbsession.rollback() > log.debug(error) > raise > > Todo funciona como debería salvo que no respondo a la petición ajax, lo que > llega es un error generado por el servidor: > Internal Server Error > The server encountered an unexpected internal server error > (generated by waitress) > > > Si hago > except Exception as error: > log.debug(error) > return Response(json.dumps('Datos con el error'), > content_type='application/json; charset=utf-8', > status=500) > Se genera la respuesta json correctamente > PERO también se genera un commit() que hace que todas las sentencias del try: > donde NO se han generado errores (del tipo que sea) se graben en la base de > datos > Esto es un problema pues la bd se me queda en un estado inconsistente > > > Si hago > except Exception as error: > request.dbsession.rollback() > log.debug(error) > return Response(json.dumps('Datos con el error'), > content_type='application/json; charset=utf-8', > status=500) > > En el servidor se lanza un error: sqlalchemy.exc.ResourceClosedError: This > transaction is closed > No se genera la respuesta json > Y llega el mismo error de antes generado por el servidor > Internal Server Error > The server encountered an unexpected internal server error > (generated by waitress) > > > > > Alguna sugerencia???, que hago mal??? > > > Gracias y saludos > > > Miguel Sánchez > > > _______________________________________________ > Python-es mailing list > Python-es@python.org > https://mail.python.org/mailman/listinfo/python-es _______________________________________________ Python-es mailing list Python-es@python.org https://mail.python.org/mailman/listinfo/python-es