SQLAlchemy scoped_session: лучший способ получить представление

Я создаю веб-приложение, используя WebApp2, SQLAlchemy, Apache, PostgrSQL и т. д. У меня есть файл config, в котором хранятся учетные данные базы данных и создается объект сеанса с использованием scoped_session. Прямо сейчас все мои файлы просмотра импортируют этот файл конфигурации и используют объект сеанса следующим образом:

some_view.py
import config

def view():
   query = config.session.query(bla bla)

Этот подход не является окончательным, и я хочу использовать наилучший возможный метод.

Здесь я хочу добиться некоторого способа получения объекта сеанса с помощью встроенного метода, связанного с decorator или webapp2, чтобы после выполнения функции представления объект сеанса закрывался. Я пробовал много способов, но не смог этого добиться. Работающий фрагмент будет высоко оценен.

Если у кого-то есть лучший подход, пожалуйста, предложите.

Спасибо

Редактировать -----

@javex: Спасибо за предложение. Я ищу класс декоратора, который при вызове вернет объект scoped_session и, когда работа будет завершена, закроет сеанс. Для справки вот пример кода, но он не работает.

class GetDBSession(object):
    """Decorator class to create DB session object"""
    def __init__(self):
        self.session = scoped_session(sessionmaker(bind=database_engine))

    def __exit__(self): #Dont know if it works
        self.session.close()

    def __call__(self): #Dont know if it works
        return self.session

И я хочу использовать его так:

@GetDBSession()
def view_func():
    #work with session object here

person user990150    schedule 25.08.2013    source источник


Ответы (1)


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

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

Они интегрируют SQLAlchemy в платформы транзакций zope и flask соответственно. В конце концов, вы хотите построить что-то вокруг обработки запросов:

try:
    result = handle_request(request)
    config.session.commit()
except:
    config.session.rollback()
    raise

Это будет зафиксировано только в том случае, если нет исключения, иначе оно откатится и передаст исключение. Как это интегрировать, зависит от WebApp2 и от того, как он позволяет эту интеграцию. Многие фреймворки предлагают какой-то подход «до обработки-после», как показано выше: вы получаете обратный вызов, который будет обрабатывать запрос, вы можете делать что-то до него, затем вызывать обратный вызов, а затем делать что-то после него. Это позволяет использовать эту аккуратную обертку try/except.

person javex    schedule 25.08.2013