Лучший подход к обработке отказов sqlalchemy

Мы экспериментировали с обработкой отладки sqlalchemy и тем, как она интегрируется с ORM. Мы изучили документы, и, похоже, советуем уловить исключение разъединения, выдать rollback() и повторить код.

например:

import sqlalchemy as SA

retry = 2
while retry:
    retry -= 1
    try:
        for name in session.query(Names):
            print name
        break
    except SA.exc.DBAPIError as exc:
        if retry and exc.connection_invalidated:
            session.rollback()
        else:
            raise

Я следую логике: вам нужно откатить любые активные транзакции и воспроизвести их, чтобы обеспечить последовательный порядок ваших действий.

НО - это означает, что добавляется много дополнительного кода для каждой функции, которая хочет работать с данными. Кроме того, в случае SELECT мы не изменяем данные, и концепция отката/повторного запроса не только неприглядна, но и нарушает принцип DRY (не повторяйте себя).

Мне было интересно, не будут ли другие люди делиться тем, как они обрабатывают разъединения с sqlalchemy.

FYI: мы используем sqlalchemy 0.9.8 и Postgres 9.2.9

Ответы

Ответ 1

Как мне нравится подходить к этому - поместить весь мой код базы данных в лямбда или закрытие и передать это в вспомогательную функцию, которая будет обрабатывать catching исключение разъединения и повторить попытку.

Итак, с вашим примером:

import sqlalchemy as SA

def main():
    def query():
        for name in session.query(Names):
            print name

    run_query(query)

def run_query(f, attempts=2):
    while attempts > 0:
        attempts -= 1
        try:
            return f() # "break" if query was successful and return any results
         except SA.exc.DBAPIError as exc:
            if attempts > 0 and exc.connection_invalidated:
                session.rollback()
            else:
                raise

Вы можете сделать это более фантастическим, передав логическое значение в run_query, чтобы обрабатывать случай, когда вы только читаете, и поэтому хотите повторить попытку, не откатываясь назад.

Это поможет вам выполнить принцип DRY, поскольку весь уродливый код котельной для управления повторными попытками + откатывается в одном месте.