|
|
|
@ -20,28 +20,25 @@ require that we provide the path to the database which can introduce
|
|
|
|
|
errors. It's a good idea to add a function that initializes the database |
|
|
|
|
for you to the application. |
|
|
|
|
|
|
|
|
|
To do this we can create a function called `init_db` that initializes the |
|
|
|
|
database. Let me show you the code first. Just add this function below |
|
|
|
|
the `connect_db` function in `flaskr.py`:: |
|
|
|
|
|
|
|
|
|
def init_db(): |
|
|
|
|
with app.app_context(): |
|
|
|
|
db = get_db() |
|
|
|
|
with app.open_resource('schema.sql', mode='r') as f: |
|
|
|
|
db.cursor().executescript(f.read()) |
|
|
|
|
db.commit() |
|
|
|
|
|
|
|
|
|
So what's happening here? Remember how we learned last chapter that the |
|
|
|
|
application context is created every time a request comes in? Here we |
|
|
|
|
don't have a request yet, so we need to create the application context by |
|
|
|
|
hand. Without an application context the :data:`~flask.g` object does not |
|
|
|
|
know yet to which application it becomes as there could be more than one! |
|
|
|
|
|
|
|
|
|
The ``with app.app_context()`` statement establishes the application |
|
|
|
|
context for us. In the body of the with statement the :data:`~flask.g` |
|
|
|
|
object will be associated with ``app``. At the end of the with statement |
|
|
|
|
the association is released and all teardown functions are executed. This |
|
|
|
|
means that our database connection is disconnected after the commit. |
|
|
|
|
To do this we can create a function and hook it into the ``flask`` command |
|
|
|
|
that initializes the database. Let me show you the code first. Just add |
|
|
|
|
this function below the `connect_db` function in `flaskr.py`:: |
|
|
|
|
|
|
|
|
|
@app.cli.command() |
|
|
|
|
def initdb(): |
|
|
|
|
"""Initializes the database.""" |
|
|
|
|
db = get_db() |
|
|
|
|
with app.open_resource('schema.sql', mode='r') as f: |
|
|
|
|
db.cursor().executescript(f.read()) |
|
|
|
|
db.commit() |
|
|
|
|
print 'Initialized the database.' |
|
|
|
|
|
|
|
|
|
The ``app.cli.command()`` decorator registers a new command with the |
|
|
|
|
``flask`` script. When the command executes Flask will automatically |
|
|
|
|
create a application context for us bound to the right application. |
|
|
|
|
Within the function we can then access :attr:`flask.g` and other things as |
|
|
|
|
we would expect. When the script ends, the application context tears down |
|
|
|
|
and the database connection is released. |
|
|
|
|
|
|
|
|
|
The :func:`~flask.Flask.open_resource` method of the application object |
|
|
|
|
is a convenient helper function that will open a resource that the |
|
|
|
@ -54,16 +51,15 @@ On that cursor there is a method to execute a complete script. Finally we
|
|
|
|
|
only have to commit the changes. SQLite 3 and other transactional |
|
|
|
|
databases will not commit unless you explicitly tell it to. |
|
|
|
|
|
|
|
|
|
Now it is possible to create a database by starting up a Python shell and |
|
|
|
|
importing and calling that function:: |
|
|
|
|
Now it is possible to create a database with the ``flask`` script:: |
|
|
|
|
|
|
|
|
|
>>> from flaskr import init_db |
|
|
|
|
>>> init_db() |
|
|
|
|
flask --app=flaskr initdb |
|
|
|
|
Initialized the database. |
|
|
|
|
|
|
|
|
|
.. admonition:: Troubleshooting |
|
|
|
|
|
|
|
|
|
If you get an exception later that a table cannot be found check that |
|
|
|
|
you did call the `init_db` function and that your table names are |
|
|
|
|
you did execute the `initdb` command and that your table names are |
|
|
|
|
correct (singular vs. plural for example). |
|
|
|
|
|
|
|
|
|
Continue with :ref:`tutorial-views` |
|
|
|
|