From b1b92284f496800a4dfd2cea72cb9be07ba8661c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 16:52:14 -0400 Subject: First cut at import of quick tutorial. --- docs/quick_tutorial/databases.rst | 184 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 docs/quick_tutorial/databases.rst (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst new file mode 100644 index 000000000..d2d2ce699 --- /dev/null +++ b/docs/quick_tutorial/databases.rst @@ -0,0 +1,184 @@ +============================== +19: Databases Using SQLAlchemy +============================== + +Store/retrieve data using the SQLAlchemy ORM atop the SQLite database. + +Background +========== + +Our Pyramid-based wiki application now needs database-backed storage of +pages. This frequently means a SQL database. The Pyramid community +strongly supports the +:ref:`SQLAlchemy ` project and its +:ref:`object-relational mapper (ORM) ` +as a convenient, Pythonic way to interface to databases. + +In this step we hook up SQLAlchemy to a SQLite database table, +providing storage and retrieval for the wikipages in the previous step. + +.. note:: + + The ``alchemy`` scaffold is really helpful for getting a + SQLAlchemy project going, including generation of the console + script. Since we want to see all the decisions, we will forgo + convenience in this tutorial and wire it up ourselves. + +Objectives +========== + +- Store pages in SQLite by using SQLAlchemy models + +- Use SQLAlchemy queries to list/add/view/edit pages + +- Provide a database-initialize command by writing a Pyramid *console + script* which can be run from the command line + +Steps +===== + +#. We are going to use the forms step as our starting point: + + .. code-block:: bash + + (env27)$ cd ..; cp -r forms databases; cd databases + +#. We need to add some dependencies in ``databases/setup.py`` as well + as an "entry point" for the command-line script: + + .. literalinclude:: databases/setup.py + :linenos: + + .. note:: + + We aren't yet doing ``python3.3 setup.py develop`` as we + are changing it later. + +#. Our configuration file at ``databases/development.ini`` wires + together some new pieces: + + .. literalinclude:: databases/development.ini + :language: ini + +#. This engine configuration now needs to be read into the application + through changes in ``databases/tutorial/__init__.py``: + + .. literalinclude:: databases/tutorial/__init__.py + :linenos: + +#. Make a command-line script at ``databases/tutorial/initialize_db.py`` + to initialize the database: + + .. literalinclude:: databases/tutorial/initialize_db.py + +#. Since ``setup.py`` changed, we now run it: + + .. code-block:: bash + + (env27)$ python setup.py develop + +#. The script references some models in ``databases/tutorial/models.py``: + + .. literalinclude:: databases/tutorial/models.py + :linenos: + +#. Let's run this console script, thus producing our database and table: + + .. code-block:: bash + + (env27)$ initialize_tutorial_db development.ini + 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") + 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] () + 2013-09-06 15:54:08,051 INFO [sqlalchemy.engine.base.Engine][MainThread] + CREATE TABLE wikipages ( + uid INTEGER NOT NULL, + title TEXT, + body TEXT, + PRIMARY KEY (uid), + UNIQUE (title) + ) + +#. With our data now driven by SQLAlchemy queries, we need to update + our ``databases/tutorial/views.py``: + + .. literalinclude:: databases/tutorial/views.py + +#. Our tests in ``databases/tutorial/tests.py`` changed to include + SQLAlchemy bootstrapping: + + .. literalinclude:: databases/tutorial/tests.py + :linenos: + +#. Run the tests in your package using ``nose``: + + .. code-block:: bash + + (env27)$ nosetests . + .. + ----------------------------------------------------------------- + Ran 2 tests in 1.141s + + OK + +#. Run your Pyramid application with: + + .. code-block:: bash + + (env27)$ pserve development.ini --reload + +#. Open ``http://localhost:6543/`` in a browser. + +Analysis +======== + +Let's start with the dependencies. We made the decision to use +``SQLAlchemy`` to talk to our database. We also, though, installed +``pyramid_tm`` and ``zope.sqlalchemy``. Why? + +Pyramid has a strong orientation towards support for ``transactions``. +Specifically, you can install a transaction manager into your app +application, either as middleware or a Pyramid "tween". Then, +just before you return the response, all transaction-aware parts of +your application are executed. + +This means Pyramid view code usually doesn't manage transactions. If +your view code or a template generates an error, the transaction manager +aborts the transaction. This is a very liberating way to write code. + +The ``pyramid_tm`` package provides a "tween" that is configured in the +``development.ini`` configuration file. That installs it. We then need +a package that makes SQLAlchemy and thus the RDBMS transaction manager +integrate with the Pyramid transaction manager. That's what +``zope.sqlalchemy`` does. + +Where do we point at the location on disk for the SQLite file? In the +configuration file. This lets consumers of our package change the +location in a safe (non-code) way. That is, in configuration. This +configuration-oriented approach isn't required in Pyramid; you can +still make such statements in your ``__init__.py`` or some companion +module. + +The ``initialize_tutorial_db`` is a nice example of framework support. +You point your setup at the location of some ``[console_scripts]`` and +these get generated into your virtualenv's ``bin`` directory. Our +console script follows the pattern of being fed a configuration file +with all the bootstrapping. It then opens SQLAlchemy and creates the +root of the wiki, which also makes the SQLite file. Note the +``with transaction.manager`` part that puts the work in the scope of a +transaction (as we aren't inside a web request where this is done +automatically.) + +The ``models.py`` does a little bit extra work to hook up SQLAlchemy +into the Pyramid transaction manager. It then declares the model for a +``Page``. + +Our views have changes primarily around replacing our dummy +dictionary-of-dictionaries data with proper database support: list the +rows, add a row, edit a row, and delete a row. + +Extra Credit +============ + +#. Why all this code? Why can't I just type 2 lines and have magic ensue? + +#. Give a try at a button that deletes a wiki page. -- cgit v1.2.3 From 0a784868bdbc3a0eb226ed00e8d89cda9d181ec5 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 17:11:42 -0400 Subject: Fix naming of virtualenv prefix. --- docs/quick_tutorial/databases.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index d2d2ce699..ea03677b2 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -41,7 +41,7 @@ Steps .. code-block:: bash - (env27)$ cd ..; cp -r forms databases; cd databases + (env)$ cd ..; cp -r forms databases; cd databases #. We need to add some dependencies in ``databases/setup.py`` as well as an "entry point" for the command-line script: @@ -75,7 +75,7 @@ Steps .. code-block:: bash - (env27)$ python setup.py develop + (env)$ python setup.py develop #. The script references some models in ``databases/tutorial/models.py``: @@ -86,7 +86,7 @@ Steps .. code-block:: bash - (env27)$ initialize_tutorial_db development.ini + (env)$ initialize_tutorial_db development.ini 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] () 2013-09-06 15:54:08,051 INFO [sqlalchemy.engine.base.Engine][MainThread] @@ -113,7 +113,7 @@ Steps .. code-block:: bash - (env27)$ nosetests . + (env)$ nosetests . .. ----------------------------------------------------------------- Ran 2 tests in 1.141s @@ -124,7 +124,7 @@ Steps .. code-block:: bash - (env27)$ pserve development.ini --reload + (env)$ pserve development.ini --reload #. Open ``http://localhost:6543/`` in a browser. -- cgit v1.2.3 From b0b28ede912c817a62a84b97c332e39eda02d166 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 16 Sep 2013 02:14:53 +0200 Subject: s/env/venv just for sake of consistency --- docs/quick_tutorial/databases.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index ea03677b2..be7fbd029 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -41,7 +41,7 @@ Steps .. code-block:: bash - (env)$ cd ..; cp -r forms databases; cd databases + (venv)$ cd ..; cp -r forms databases; cd databases #. We need to add some dependencies in ``databases/setup.py`` as well as an "entry point" for the command-line script: @@ -75,7 +75,7 @@ Steps .. code-block:: bash - (env)$ python setup.py develop + (venv)$ python setup.py develop #. The script references some models in ``databases/tutorial/models.py``: @@ -86,7 +86,7 @@ Steps .. code-block:: bash - (env)$ initialize_tutorial_db development.ini + (venv)$ initialize_tutorial_db development.ini 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] () 2013-09-06 15:54:08,051 INFO [sqlalchemy.engine.base.Engine][MainThread] @@ -113,7 +113,7 @@ Steps .. code-block:: bash - (env)$ nosetests . + (venv)$ nosetests . .. ----------------------------------------------------------------- Ran 2 tests in 1.141s @@ -124,7 +124,7 @@ Steps .. code-block:: bash - (env)$ pserve development.ini --reload + (venv)$ pserve development.ini --reload #. Open ``http://localhost:6543/`` in a browser. -- cgit v1.2.3 From d749bf4c987c4ab90bd5f89326e7d4059e4f47b3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 16 Sep 2013 02:18:11 +0200 Subject: make example links clickable, for convenience --- docs/quick_tutorial/databases.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index be7fbd029..e8786a046 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -126,7 +126,7 @@ Steps (venv)$ pserve development.ini --reload -#. Open ``http://localhost:6543/`` in a browser. +#. Open http://localhost:6543/ in a browser. Analysis ======== -- cgit v1.2.3 From 187104fd81418beeb51592913041d9751bafe08d Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 25 Sep 2013 09:27:43 -0400 Subject: Quick Tutorial: Improve the setup instructions (adapted from Steve Piercy's work), particularly for Windows. Change all the steps to use $VENV/bin prefixes on commands (don't presume that they have done source env/bin/activate). --- docs/quick_tutorial/databases.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index e8786a046..978ef6982 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -41,7 +41,7 @@ Steps .. code-block:: bash - (venv)$ cd ..; cp -r forms databases; cd databases + $ cd ..; cp -r forms databases; cd databases #. We need to add some dependencies in ``databases/setup.py`` as well as an "entry point" for the command-line script: @@ -75,7 +75,7 @@ Steps .. code-block:: bash - (venv)$ python setup.py develop + $ $VENV/bin/python setup.py develop #. The script references some models in ``databases/tutorial/models.py``: @@ -86,7 +86,7 @@ Steps .. code-block:: bash - (venv)$ initialize_tutorial_db development.ini + $ initialize_tutorial_db development.ini 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages") 2013-09-06 15:54:08,050 INFO [sqlalchemy.engine.base.Engine][MainThread] () 2013-09-06 15:54:08,051 INFO [sqlalchemy.engine.base.Engine][MainThread] @@ -113,7 +113,7 @@ Steps .. code-block:: bash - (venv)$ nosetests . + $ $VENV/bin/nosetests . .. ----------------------------------------------------------------- Ran 2 tests in 1.141s @@ -124,7 +124,7 @@ Steps .. code-block:: bash - (venv)$ pserve development.ini --reload + $ $VENV/bin/pserve development.ini --reload #. Open http://localhost:6543/ in a browser. -- cgit v1.2.3 From 34e974e360184baef873da55f31379697e367f32 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 25 Sep 2013 12:08:33 -0400 Subject: Get pyramid_chameleon added to the quick tutorial, plus some other fixes for Python 3. --- docs/quick_tutorial/databases.rst | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index 978ef6982..83cf33862 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -37,6 +37,15 @@ Objectives Steps ===== +.. warning:: + + Your Python might not have SQLite bundled. If not, install it into + your virtual environment with: + + .. code-block:: bash + + $ $VENV/bin/easy_install sphinx pysqlite + #. We are going to use the forms step as our starting point: .. code-block:: bash -- cgit v1.2.3 From b731b5fca253d9d95b3307490aa585e194676c01 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Thu, 26 Sep 2013 17:41:44 -0400 Subject: Quick Tour: shorten the setup part and point to Quick Tutorial Requirements for more explanation. Cross link each Quick Tour section with its Quick Tutorial match. --- docs/quick_tutorial/databases.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/quick_tutorial/databases.rst') diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index 83cf33862..93a02ffc7 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -1,3 +1,5 @@ +.. _qtut_databases: + ============================== 19: Databases Using SQLAlchemy ============================== -- cgit v1.2.3