diff --git a/docs/extensiondev.rst b/docs/extensiondev.rst index a5cc2aa4..2c79c6ab 100644 --- a/docs/extensiondev.rst +++ b/docs/extensiondev.rst @@ -182,7 +182,7 @@ Here's the contents of the `flaskext/sqlite3.py` for copy/paste:: def __init__(self, app): self.app = app self.app.config.setdefault('SQLITE3_DATABASE', ':memory:') - self.app.after_request(self.after_request) + self.app.teardown_request(self.teardown_request) self.app.before_request(self.before_request) def connect(self): @@ -192,10 +192,9 @@ Here's the contents of the `flaskext/sqlite3.py` for copy/paste:: ctx = _request_ctx_stack.top ctx.sqlite3_db = self.connect() - def after_request(self, response): + def teardown_request(self, exception): ctx = _request_ctx_stack.top ctx.sqlite3_db.close() - return response def get_db(self): ctx = _request_ctx_stack.top @@ -211,7 +210,7 @@ So here's what these lines of code do: 2. We create a class for our extension that requires a supplied `app` object, sets a configuration for the database if it's not there (:meth:`dict.setdefault`), and attaches `before_request` and - `after_request` handlers. + `teardown_request` handlers. 3. Next, we define a `connect` function that opens a database connection. 4. Then we set up the request handlers we bound to the app above. Note here that we're attaching our database connection to the top request context via @@ -264,7 +263,7 @@ Our extension could add an `init_app` function as follows:: def init_app(self, app): self.app = app self.app.config.setdefault('SQLITE3_DATABASE', ':memory:') - self.app.after_request(self.after_request) + self.app.teardown_request(self.teardown_request) self.app.before_request(self.before_request) def connect(self): @@ -274,10 +273,9 @@ Our extension could add an `init_app` function as follows:: ctx = _request_ctx_stack.top ctx.sqlite3_db = self.connect() - def after_request(self, response): + def teardown_request(self, exception): ctx = _request_ctx_stack.top ctx.sqlite3_db.close() - return response def get_db(self): ctx = _request_ctx_stack.top diff --git a/docs/patterns/sqlalchemy.rst b/docs/patterns/sqlalchemy.rst index 24e9f013..5a33d1f6 100644 --- a/docs/patterns/sqlalchemy.rst +++ b/docs/patterns/sqlalchemy.rst @@ -65,10 +65,9 @@ automatically remove database sessions at the end of the request for you:: from yourapplication.database import db_session - @app.after_request - def shutdown_session(response): + @app.teardown_request + def shutdown_session(exception=None): db_session.remove() - return response Here is an example model (put this into `models.py`, e.g.):: @@ -140,10 +139,9 @@ each request. Put this into your application module:: from yourapplication.database import db_session - @app.after_request - def shutdown_session(response): + @app.teardown_request + def shutdown_session(exception=None): db_session.remove() - return response Here is an example table and model (put this into `models.py`):: diff --git a/docs/patterns/sqlite3.rst b/docs/patterns/sqlite3.rst index 68833234..d0ec5a27 100644 --- a/docs/patterns/sqlite3.rst +++ b/docs/patterns/sqlite3.rst @@ -5,7 +5,7 @@ Using SQLite 3 with Flask In Flask you can implement the opening of database connections at the beginning of the request and closing at the end with the -:meth:`~flask.Flask.before_request` and :meth:`~flask.Flask.after_request` +:meth:`~flask.Flask.before_request` and :meth:`~flask.Flask.teardown_request` decorators in combination with the special :class:`~flask.g` object. So here is a simple example of how you can use SQLite 3 with Flask:: @@ -22,10 +22,34 @@ So here is a simple example of how you can use SQLite 3 with Flask:: def before_request(): g.db = connect_db() - @app.after_request - def after_request(response): + @app.teardown_request + def teardown_request(exception): g.db.close() - return response + +Connect on Demand +----------------- + +The downside of this approach is that this will only work if Flask +executed the before-request handlers for you. If you are attempting to +use the database from a script or the interactive Python shell you would +have to do something like this:: + + with app.test_request_context() + app.preprocess_request() + # now you can use the g.db object + +In order to trigger the execution of the connection code. You won't be +able to drop the dependency on the request context this way, but you could +make it so that the application connects when necessary:: + + def get_connection(): + db = getattr(g, '_db', None) + if db is None: + db = g._db = connect_db() + return db + +Downside here is that you have to use ``db = get_connection()`` instead of +just being able to use ``g.db`` directly. .. _easy-querying: diff --git a/docs/tutorial/dbcon.rst b/docs/tutorial/dbcon.rst index b2a626f9..1d9d41f9 100644 --- a/docs/tutorial/dbcon.rst +++ b/docs/tutorial/dbcon.rst @@ -9,22 +9,8 @@ connection in all our functions so it makes sense to initialize them before each request and shut them down afterwards. Flask allows us to do that with the :meth:`~flask.Flask.before_request`, -:meth:`~flask.Flask.after_request` and :meth:`~flask.Flask.teardown_request` -decorators. In debug mode, if an error is raised, -:meth:`~flask.Flask.after_request` won't be run, and you'll have access to the -db connection in the interactive debugger:: - - @app.before_request - def before_request(): - g.db = connect_db() - - @app.after_request - def after_request(response): - g.db.close() - return response - -If you want to guarantee that the connection is always closed in debug mode, you -can close it in a function decorated with :meth:`~flask.Flask.teardown_request`:: +:meth:`~flask.Flask.teardown_request` and :meth:`~flask.Flask.teardown_request` +decorators:: @app.before_request def before_request(): @@ -36,18 +22,17 @@ can close it in a function decorated with :meth:`~flask.Flask.teardown_request`: Functions marked with :meth:`~flask.Flask.before_request` are called before a request and passed no arguments. Functions marked with -:meth:`~flask.Flask.after_request` are called after a request and +:meth:`~flask.Flask.teardown_request` are called after a request and passed the response that will be sent to the client. They have to return -that response object or a different one. In this case we just return it -unchanged. - -Functions marked with :meth:`~flask.Flask.teardown_request` get called after the +that response object or a different one. They are however not guaranteed +to be executed if an exception is raised, this is where functions marked with +:meth:`~flask.Flask.teardown_request` come in. They get called after the response has been constructed. They are not allowed to modify the request, and their return values are ignored. If an exception occurred while the request was -being processed, it is passed to each function; otherwise, None is passed in. +being processed, it is passed to each function; otherwise, `None` is passed in. We store our current database connection on the special :data:`~flask.g` -object that flask provides for us. This object stores information for one +object that Flask provides for us. This object stores information for one request only and is available from within each function. Never store such things on other objects because this would not work with threaded environments. That special :data:`~flask.g` object does some magic behind