def test_manual_enter_and_exit_out_of_order_exit_raises_assertion(cxn): t1, t2 = Transaction(cxn), Transaction(cxn) t1.__enter__() t2.__enter__() with pytest.raises( AssertionError, match=re.escape( 'Out-of-order Transaction context exits. Are you calling ' '__exit__() manually and getting it wrong?')): t1.__exit__(None, None, None)
def test_explicit_rollback_required_after_handling_sql_exception_otherwise_exception_is_raised( cxn): txn = Transaction(cxn) txn.__enter__() with pytest.raises(psycopg2.ProgrammingError): cxn.cursor().execute('SELECT * FROM this_table_does_not_exist') with pytest.raises( Exception, match=re.escape( 'SQL error occurred within current transaction. ' 'Transaction.rollback() must be called before exiting ' 'transaction context.')): txn.__exit__(None, None, None)
def test_manual_transaction_management_inside_context_explicit_commit( cxn, other_cxn): def classic_method(cxn): assert cxn.autocommit is False insert_row(cxn, 'inner') cxn.commit() txn = Transaction(cxn).__enter__() insert_row(cxn, 'outer') classic_method(cxn) # All changes are committed and visible immediately :-( assert_rows(other_cxn, {'inner', 'outer'}) # Context exit fails :-(( with pytest.raises(psycopg2.InternalError, match='no such savepoint'): txn.__exit__(None, None, None)
def test_manual_transaction_management_inside_context_implicit_rollback( cxn, other_cxn): def method(cxn): # This method implicitly rolls back the current transaction :-( # See: https://github.com/psycopg/psycopg2/issues/950 cxn.set_client_encoding('LATIN1') txn = Transaction(cxn).__enter__() insert_row(cxn, 'outer') assert_in_transaction(cxn) method(cxn) assert_not_in_transaction(cxn) # Context exit fails :-( with pytest.raises(psycopg2.InternalError, match='no such savepoint'): txn.__exit__(None, None, None) # All changes are discarded :-(( assert_rows(other_cxn, set())
def test_manual_transaction_management_inside_context_explicit_rollback( cxn, other_cxn): def classic_method(cxn): assert cxn.autocommit is False insert_row(cxn, 'inner') cxn.rollback() txn = Transaction(cxn).__enter__() insert_row(cxn, 'outer') assert_in_transaction(cxn) classic_method(cxn) assert_not_in_transaction(cxn) # Context exit fails :-( with pytest.raises(psycopg2.InternalError, match='no such savepoint'): txn.__exit__(None, None, None) # All changes are discarded :-(( assert_rows(other_cxn, set())