diff --git a/docs/tutorial/dbinit.rst b/docs/tutorial/dbinit.rst index 980caca0..0d92f5be 100644 --- a/docs/tutorial/dbinit.rst +++ b/docs/tutorial/dbinit.rst @@ -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` diff --git a/docs/tutorial/setup.rst b/docs/tutorial/setup.rst index 65d4b3f2..0b76e105 100644 --- a/docs/tutorial/setup.rst +++ b/docs/tutorial/setup.rst @@ -29,7 +29,6 @@ config from the same file, in `flaskr.py`:: # Load default config and override config from an environment variable app.config.update(dict( DATABASE=os.path.join(app.root_path, 'flaskr.db'), - DEBUG=True, SECRET_KEY='development key', USERNAME='admin', PASSWORD='default' @@ -71,10 +70,7 @@ module. Flask will the initialize the variable from that module. Note that in all cases only variable names that are uppercase are considered. The ``SECRET_KEY`` is needed to keep the client-side sessions secure. -Choose that key wisely and as hard to guess and complex as possible. The -debug flag enables or disables the interactive debugger. *Never leave -debug mode activated in a production system*, because it will allow users to -execute code on the server! +Choose that key wisely and as hard to guess and complex as possible. We will also add a method that allows for easily connecting to the specified database. This can be used to open a connection on request and @@ -92,16 +88,14 @@ tuples. rv.row_factory = sqlite3.Row return rv -Finally we just add a line to the bottom of the file that fires up the -server if we want to run that file as a standalone application:: - - if __name__ == '__main__': - app.run() - With that out of the way you should be able to start up the application without problems. Do this with the following command:: - python flaskr.py + flask --app=flaskr --debug run + +The ``--debug`` flag enables or disables the interactive debugger. *Never +leave debug mode activated in a production system*, because it will allow +users to execute code on the server! You will see a message telling you that server has started along with the address at which you can access it. diff --git a/examples/flaskr/.gitignore b/examples/flaskr/.gitignore new file mode 100644 index 00000000..fb46a3af --- /dev/null +++ b/examples/flaskr/.gitignore @@ -0,0 +1 @@ +flaskr.db diff --git a/examples/flaskr/flaskr.py b/examples/flaskr/flaskr.py index 384162af..2cd2fd19 100644 --- a/examples/flaskr/flaskr.py +++ b/examples/flaskr/flaskr.py @@ -37,13 +37,14 @@ def connect_db(): return rv -def init_db(): +@app.cli.command() +def initdb(): """Creates the database tables.""" - with app.app_context(): - db = get_db() - with app.open_resource('schema.sql', mode='r') as f: - db.cursor().executescript(f.read()) - db.commit() + db = get_db() + with app.open_resource('schema.sql', mode='r') as f: + db.cursor().executescript(f.read()) + db.commit() + print('Initialized the database.') def get_db(): @@ -76,7 +77,7 @@ def add_entry(): abort(401) db = get_db() db.execute('insert into entries (title, text) values (?, ?)', - [request.form['title'], request.form['text']]) + [request.form['title'], request.form['text']]) db.commit() flash('New entry was successfully posted') return redirect(url_for('show_entries')) @@ -102,8 +103,3 @@ def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('show_entries')) - - -if __name__ == '__main__': - init_db() - app.run()