Search code examples
pythonpeewee

Peewee transaction seems not work


I met an transaction problem when I used the python orm peewee these days. I save two book instances using this orm, and beween the two savings I raise an exception so I except that none of them are saved to database, but it doesn't work. Could anyone explain why? I am new to python, thanks.

this code is below:

from peewee import *

def get_db():
    return SqliteDatabase("test.db")

class Book(Model):
    id = PrimaryKeyField()
    name = CharField()
    class Meta:
        database = get_db()

def test_transaction():
    book1 = Book(name="book1")
    book2 = Book(name="book2")

    db = get_db()
    db.create_tables([Book], safe=True)

    try:
        with db.transaction() as tran:
            book1.save()
            raise ProgrammingError("test")
            book2.save()
    except:
        pass

    for book in Book.select():
        print(book.name)


if __name__ == '__main__':
    test_transaction()

Solution

  • The problem is that when you are calling "get_db()" you are instantiating new database objects. Databases are stateful, in that they manage the active connection for a given thread. So what you've essentially got is two different databases, one that your models are associated with, and one that has your connection and transaction. When you call db.transaction() a transaction is taking place, but not on the connection you think it is.

    Change the code to read as follows and it will work like you expect.

    book1 = Book(name='book1')
    book2 = Book(name='book2')
    
    db = Book._meta.database
    # ...