If an exception occurs in a wrapped block, the current transaction/savepoint will be rolled back. Otherwise the statements will be committed at the end of the wrapped block.

    Note

    While inside a block wrapped by the context manager, you can explicitly rollback or commit at any point by calling Transaction.rollback() or Transaction.commit(). When you do this inside a wrapped block of code, a new transaction will be started automatically.

    Note

    atomic() can be used as either a context manager or a decorator.

    Using atomic as context manager:

    1. db = SqliteDatabase(':memory:')
    2. with db.atomic() as txn:
    3. # This is the outer-most level, so this block corresponds to
    4. # a transaction.
    5. User.create(username='charlie')
    6. with db.atomic() as nested_txn:
    7. # This block corresponds to a savepoint.
    8. User.create(username='huey')
    9. # This will roll back the above create() query.
    10. nested_txn.rollback()
    11. User.create(username='mickey')
    12. # When the block ends, the transaction is committed (assuming no error
    13. # occurs). At that point there will be two users, "charlie" and "mickey".
    1. try:
    2. with db.atomic():
    3. user = User.create(username=username)
    4. return 'Success'
    5. except peewee.IntegrityError:
    6. return 'Failure: %s is already in use.' % username

    Decorator

    Using atomic as a decorator:

    atomic() provides transparent nesting of transactions. When using , the outer-most call will be wrapped in a transaction, and any nested calls will use savepoints.

    1. with db.atomic() as txn:
    2. perform_operation()
    3. with db.atomic() as nested_txn:
    4. perform_another_operation()

    Peewee supports nested transactions through the use of savepoints (for more information, see savepoint()).

    Explicit transaction

    If you wish to explicitly run code in a transaction, you can use transaction(). Like , transaction() can be used as a context manager or as a decorator.

    If an exception occurs in a wrapped block, the transaction will be rolled back. Otherwise the statements will be committed at the end of the wrapped block.

    1. db = SqliteDatabase(':memory:')
    2. with db.transaction() as txn:
    3. # Delete the user and their associated tweets.

    Transactions can be explicitly committed or rolled-back within the wrapped block. When this happens, a new transaction will be started.

    If you attempt to nest transactions with peewee using the context manager, only the outer-most transaction will be used. However if an exception occurs in a nested block, this can lead to unpredictable behavior, so it is strongly recommended that you use .

    Just as you can explicitly create transactions, you can also explicitly create savepoints using the method. Savepoints must occur within a transaction, but can be nested arbitrarily deep.

    1. with db.transaction() as txn:
    2. with db.savepoint() as sp:
    3. User.create(username='mickey')
    4. with db.savepoint() as sp2:
    5. User.create(username='zaizee')
    6. sp2.rollback() # "zaizee" will not be saved, but "mickey" will be.

    Warning

    If you manually commit or roll back a savepoint, a new savepoint will not automatically be created. This differs from the behavior of transaction, which will automatically open a new transaction after manual commit/rollback.

    Autocommit Mode

    By default, Peewee operates in autocommit mode, such that any statements executed outside of a transaction are run in their own transaction. To group multiple statements into a transaction, Peewee provides the context-manager/decorator. This should cover all use-cases, but in the unlikely event you want to temporarily disable Peewee’s transaction management completely, you can use the Database.manual_commit() context-manager/decorator.

    Here is how you might emulate the behavior of the context manager:

    1. with db.manual_commit():
    2. db.begin() # Have to begin transaction explicitly.
    3. try:
    4. user.delete_instance(recursive=True)
    5. except:
    6. db.rollback() # Rollback! An error occurred.
    7. raise
    8. else:
    9. try:
    10. db.commit() # Commit changes.
    11. except:
    12. db.rollback()