.. _tutorial-dbcon: Шаг 3: Соединения с базой данных -------------------------------- Мы создали функцию для установления соединения с базой данных с помощью `connect_db`, но сама по себе она не совсем пригодна. Создание и закрытие соединения с базой данных каждый раз - очень неэффективно, поэтому мы хотели бы держать его подольше. Поскольку соединения с базой данных инкапсулирует транзакцию, нам также надо убедиться, что в один момент времени соединением пользуется только один запрос. В этом месте в игру вступает контекст приложения. С этого места и начнём. Flask обеспечивает нас двумя контекстами: контекстом приложения и контекстом запроса. На данный момент всё, что вы должны знать - это то, что есть специальные переменные, которые используют их. Например, переменная :data:`~flask.request` - это объект запроса, ассоциированный с текущим запросом, в то время как :data:`~flask.g` - это переменная общего назначения, которая ассоциирована с текущим контекстом приложения. Чуть позже мы коснёмся этого более детально. Всё, что вам надо знать на этот момент - это то, что вы можете безопасно сохранять информацию в объекте :data:`~flask.g`. Итак, когда же вы начнёте её туда сохранять? Чтобы сделать это, вы можете сделать функцию-помощник (helper). Когда она будет запущена в первый раз, она создаст для текущего контекста соединение с базой данных, и её успешные вызовы будут возвращать уже установленное соединение:: def get_db(): """Если ещё нет соединения с базой данных, открыть новое - для текущего контекста приложения """ if not hasattr(g, 'sqlite_db'): g.sqlite_db = connect_db() return g.sqlite_db Итак, теперь мы знаем, как соединиться, но вот как мы можем соответственно разорвать соединение? Для этого Flask обеспечил нас декоратором :meth:`~flask.Flask.teardown_appcontext`. Он выполняется каждый раз, когда происходит разрыв контекста приложения:: @app.teardown_appcontext def close_db(error): """Closes the database again at the end of the request.""" if hasattr(g, 'sqlite_db'): g.sqlite_db.close() Функция, обозначенная как :meth:`~flask.Flask.teardown_appcontext` вызывается каждый раз при разрыве контекста приложения. Что это значит? В сущности, контекст приложения уже создан до того, как пришёл запрос, и он уничтожается (разрывается) когда запрос заканчивается. Разрыв может произойти по двум причинам: или всё прошло хорошо (параметр ошибки в этом случае будет `None`), или произошло исключение, и в этом случае функции разрыва будет передана ошибка. Непонятно, что означают эти контексты? Для дальнейшего изучения загляните в раздел документации :ref:`app-context`. Продолжение: :ref:`tutorial-dbinit`. .. hint:: Куда мне поместить этот код? Если вы следовали указаниям этого учебника, вас может немного озадачить, куда поместить код из этого и следующего шага. Было бы логичным сгруппировать эти функции уровня модуля вместе, и разместить ваши новые функции ``get_db`` и ``close_db`` под функцией ``connect_db`` (аккуратно следуя учебнику). Если вам нужно время, чтобы сориентироваться, взгляните как организованы `исходные тексты примера`_. В Flask, вы можете поместить весь код вашего приложения в единственный модуль Python. Однако это вовсе необязательно, и если ваше приложение :ref:`растёт larger `, будет разумным этого не делать. .. _исходные тексты примера: http://github.com/mitsuhiko/flask/tree/master/examples/flaskr/ `Оригинал этой страницы `_