Updated documentation to use teardown request where appropriate
This commit is contained in:
parent
ba6bf23e0d
commit
a9fc040c39
4 changed files with 45 additions and 40 deletions
|
|
@ -182,7 +182,7 @@ Here's the contents of the `flaskext/sqlite3.py` for copy/paste::
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.app.config.setdefault('SQLITE3_DATABASE', ':memory:')
|
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)
|
self.app.before_request(self.before_request)
|
||||||
|
|
||||||
def connect(self):
|
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 = _request_ctx_stack.top
|
||||||
ctx.sqlite3_db = self.connect()
|
ctx.sqlite3_db = self.connect()
|
||||||
|
|
||||||
def after_request(self, response):
|
def teardown_request(self, exception):
|
||||||
ctx = _request_ctx_stack.top
|
ctx = _request_ctx_stack.top
|
||||||
ctx.sqlite3_db.close()
|
ctx.sqlite3_db.close()
|
||||||
return response
|
|
||||||
|
|
||||||
def get_db(self):
|
def get_db(self):
|
||||||
ctx = _request_ctx_stack.top
|
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,
|
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
|
sets a configuration for the database if it's not there
|
||||||
(:meth:`dict.setdefault`), and attaches `before_request` and
|
(: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.
|
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
|
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
|
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):
|
def init_app(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.app.config.setdefault('SQLITE3_DATABASE', ':memory:')
|
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)
|
self.app.before_request(self.before_request)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
|
|
@ -274,10 +273,9 @@ Our extension could add an `init_app` function as follows::
|
||||||
ctx = _request_ctx_stack.top
|
ctx = _request_ctx_stack.top
|
||||||
ctx.sqlite3_db = self.connect()
|
ctx.sqlite3_db = self.connect()
|
||||||
|
|
||||||
def after_request(self, response):
|
def teardown_request(self, exception):
|
||||||
ctx = _request_ctx_stack.top
|
ctx = _request_ctx_stack.top
|
||||||
ctx.sqlite3_db.close()
|
ctx.sqlite3_db.close()
|
||||||
return response
|
|
||||||
|
|
||||||
def get_db(self):
|
def get_db(self):
|
||||||
ctx = _request_ctx_stack.top
|
ctx = _request_ctx_stack.top
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,9 @@ automatically remove database sessions at the end of the request for you::
|
||||||
|
|
||||||
from yourapplication.database import db_session
|
from yourapplication.database import db_session
|
||||||
|
|
||||||
@app.after_request
|
@app.teardown_request
|
||||||
def shutdown_session(response):
|
def shutdown_session(exception=None):
|
||||||
db_session.remove()
|
db_session.remove()
|
||||||
return response
|
|
||||||
|
|
||||||
Here is an example model (put this into `models.py`, e.g.)::
|
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
|
from yourapplication.database import db_session
|
||||||
|
|
||||||
@app.after_request
|
@app.teardown_request
|
||||||
def shutdown_session(response):
|
def shutdown_session(exception=None):
|
||||||
db_session.remove()
|
db_session.remove()
|
||||||
return response
|
|
||||||
|
|
||||||
Here is an example table and model (put this into `models.py`)::
|
Here is an example table and model (put this into `models.py`)::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Using SQLite 3 with Flask
|
||||||
|
|
||||||
In Flask you can implement the opening of database connections at the
|
In Flask you can implement the opening of database connections at the
|
||||||
beginning of the request and closing at the end with 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.
|
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::
|
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():
|
def before_request():
|
||||||
g.db = connect_db()
|
g.db = connect_db()
|
||||||
|
|
||||||
@app.after_request
|
@app.teardown_request
|
||||||
def after_request(response):
|
def teardown_request(exception):
|
||||||
g.db.close()
|
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:
|
.. _easy-querying:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,8 @@ connection in all our functions so it makes sense to initialize them
|
||||||
before each request and shut them down afterwards.
|
before each request and shut them down afterwards.
|
||||||
|
|
||||||
Flask allows us to do that with the :meth:`~flask.Flask.before_request`,
|
Flask allows us to do that with the :meth:`~flask.Flask.before_request`,
|
||||||
:meth:`~flask.Flask.after_request` and :meth:`~flask.Flask.teardown_request`
|
:meth:`~flask.Flask.teardown_request` and :meth:`~flask.Flask.teardown_request`
|
||||||
decorators. In debug mode, if an error is raised,
|
decorators::
|
||||||
: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`::
|
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def 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
|
Functions marked with :meth:`~flask.Flask.before_request` are called before
|
||||||
a request and passed no arguments. Functions marked with
|
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
|
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
|
that response object or a different one. They are however not guaranteed
|
||||||
unchanged.
|
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
|
||||||
Functions marked with :meth:`~flask.Flask.teardown_request` get called after the
|
|
||||||
response has been constructed. They are not allowed to modify the request, and
|
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
|
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`
|
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
|
request only and is available from within each function. Never store such
|
||||||
things on other objects because this would not work with threaded
|
things on other objects because this would not work with threaded
|
||||||
environments. That special :data:`~flask.g` object does some magic behind
|
environments. That special :data:`~flask.g` object does some magic behind
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue