Search code examples
pythonsqlalchemypyramid

Transaction manager revert/rollback last commit


I try to speedup my tests by putting test data from test case setUp() to setUpClass()/teardownClass class method, so it does not recreate same select only fixture for every test in test case.

@classmethod
def setUpClass(cls):
    plant.StuffFactory() #plant stuff with FactoryBoy
    transaction.commit()

@classmethod
def tearDownClass(cls):
    session.query(models.Stuff).delete() # delete planted stuff
    transaction.commit()

But i don't like deleting stuff with session.delete on my own, because i use many models and don't want track what i planted. I want something like

@classmethod
def tearDownClass(cls):
    session.clear() #delete all
    transaction.commit()

But session.close() or session.remove() will not affect committed data. So i seek some way to "cancel" setUpClass transaction.commit() like i don't plant anything.

I try nested transactions and savepoints but again they works only if data not committed yet.

Any pointers?


Solution

  • If you don't want things to be committed, simply don't call transaction.commit() :)

    @classmethod
    def setUpClass(cls):
        plant.StuffFactory() #plant stuff with FactoryBoy
        # you may possibly want to flush the session, so everything has proper IDs etc.
        DBSession.flush() 
        # let the transaction continue for the duration of the test
    
    @classmethod
    def tearDownClass(cls):
        # let the database make everything as if nothing happened
        transaction.rollback()
    

    This would require that none of your code under test does explicit transaction management (transaction.commit() \ transaction.rollback() in application code), but that's a bad practice anyway:

    As a general rule, the application should manage the lifecycle of the session externally to functions that deal with specific data. This is a fundamental separation of concerns which keeps data-specific operations agnostic of the context in which they access and manipulate that data.

    Session Basics, SQLAlchemy Documentation (https://docs.sqlalchemy.org/en/13/orm/session_basics.html)