Как правильно реализовать Peewee Rollback? - PullRequest
0 голосов
/ 28 января 2020

У меня есть код, использующий TestModel, который наследует playhouse.postgres_ext.Model, экземпляр PostgreSQL как sql_db , экземпляр SMTP как smtp для уведомления

@sql_db.atomic()
def update_jersey():
    TestModel.update(TestModel.jersey_number=24).where(TestModel.first_name="kobe").execute()
    smtp.sendmail(*args, **kwargs)

Я хочу, чтобы мой TestModel.update () выполнял откат при сбое smtp.sendmail (), но в настоящее время код не откатывает обновление.

Я также попытался использовать приведенную ниже логи c но все же откат не работает.

with sql_db.manual_commit():
    sql_db.begin()
    try:
        TestModel.update()
        smtp.sendmail()
    except Exception:
        sql_db.rollback()
    else:
        sql_db.commit()

Я также попробовал sql_db.transaction () как txn , но все равно не повезло.

Как я могу реализовать откат с учетом того, что исключение вызвано другой функцией и не связано с SQL?

1 Ответ

0 голосов
/ 29 января 2020

В тестах видно, что декоратор и диспетчер контекста atomic неявно откатятся, если в обернутом блоке произойдет ошибка.

Документы здесь:

http://docs.peewee-orm.com/en/latest/peewee/database.html#managing -транзакций

Вот минимальный пример:

db = SqliteDatabase(':memory:')

class R(Model):
    value = IntegerField()
    class Meta:
        database = db

db.create_tables([R])

with db.atomic():
    R.create(value=1)

# Explicit rollback
with db.atomic() as txn:
    R.create(value=2)
    txn.rollback()

# Implicit rollback because of exception.
try:
    with db.atomic():
        R.create(value=3)
        4 / 0
except ZeroDivisionError:
    pass

print([x.value for x in R])
# Prints:
# [1]

RIP Кобе

...