summaryrefslogtreecommitdiff
path: root/docs/quick_tutorial
diff options
context:
space:
mode:
authorSteve Piercy <web@stevepiercy.com>2016-04-16 13:22:31 -0700
committerSteve Piercy <web@stevepiercy.com>2016-04-16 13:22:31 -0700
commit8bca48a37f5a0f79976d975aa3afd5760688a89c (patch)
tree9929337b6a5007c60a0cf55d67e80bf3d7dd8584 /docs/quick_tutorial
parent59c8fc7919730c3f3100ad84250a788e2d0a3bb0 (diff)
downloadpyramid-8bca48a37f5a0f79976d975aa3afd5760688a89c.tar.gz
pyramid-8bca48a37f5a0f79976d975aa3afd5760688a89c.tar.bz2
pyramid-8bca48a37f5a0f79976d975aa3afd5760688a89c.zip
quick_tutorial cleanup
- replace nose with pytest - cleanup databases.rst
Diffstat (limited to 'docs/quick_tutorial')
-rw-r--r--docs/quick_tutorial/databases.rst186
-rw-r--r--docs/quick_tutorial/databases/sqltutorial.sqlitebin12288 -> 0 bytes
2 files changed, 92 insertions, 94 deletions
diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst
index f9f548585..c8d87c180 100644
--- a/docs/quick_tutorial/databases.rst
+++ b/docs/quick_tutorial/databases.rst
@@ -4,37 +4,39 @@
19: Databases Using SQLAlchemy
==============================
-Store/retrieve data using the SQLAlchemy ORM atop the SQLite database.
+Store and 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 <sqla:index_toplevel>` project and its
-:ref:`object-relational mapper (ORM) <sqla:ormtutorial_toplevel>`
-as a convenient, Pythonic way to interface to databases.
+Our Pyramid-based wiki application now needs database-backed storage of pages.
+This frequently means an SQL database. The Pyramid community strongly supports
+the :ref:`SQLAlchemy <sqla:index_toplevel>` project and its
+:ref:`object-relational mapper (ORM) <sqla:ormtutorial_toplevel>` 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.
+In this step we hook up SQLAlchemy to a SQLite database table, providing
+storage and retrieval for the wiki pages 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.
+ The ``alchemy`` scaffold is really helpful for getting an 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
+- Store pages in SQLite by using SQLAlchemy models.
-- Use SQLAlchemy queries to list/add/view/edit pages
+- 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.
-- Provide a database-initialize command by writing a Pyramid *console
- script* which can be run from the command line
Steps
=====
@@ -45,31 +47,31 @@ Steps
$ 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:
+#. 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 ``$VENV/bin/pip install -e .`` as we
- will change it later.
+ We aren't yet doing ``$VENV/bin/pip install -e .`` as we will change it
+ later.
-#. Our configuration file at ``databases/development.ini`` wires
- together some new pieces:
+#. 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``:
+#. 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:
+#. Make a command-line script at ``databases/tutorial/initialize_db.py`` to
+ initialize the database:
.. literalinclude:: databases/tutorial/initialize_db.py
:linenos:
@@ -90,51 +92,49 @@ Steps
.. code-block:: bash
$ $VENV/bin/initialize_tutorial_db development.ini
- 2015-06-01 11:22:52,650 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
- 2015-06-01 11:22:52,650 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
- 2015-06-01 11:22:52,651 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
- 2015-06-01 11:22:52,651 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
- 2015-06-01 11:22:52,652 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages")
- 2015-06-01 11:22:52,652 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
- 2015-06-01 11:22:52,653 INFO [sqlalchemy.engine.base.Engine][MainThread]
+
+ 2016-04-16 13:01:33,055 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
+ 2016-04-16 13:01:33,055 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
+ 2016-04-16 13:01:33,056 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
+ 2016-04-16 13:01:33,056 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
+ 2016-04-16 13:01:33,057 INFO [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("wikipages")
+ 2016-04-16 13:01:33,057 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
+ 2016-04-16 13:01:33,058 INFO [sqlalchemy.engine.base.Engine][MainThread]
CREATE TABLE wikipages (
- uid INTEGER NOT NULL,
- title TEXT,
- body TEXT,
- PRIMARY KEY (uid),
- UNIQUE (title)
+ uid INTEGER NOT NULL,
+ title TEXT,
+ body TEXT,
+ PRIMARY KEY (uid),
+ UNIQUE (title)
)
- 2015-06-01 11:22:52,653 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
- 2015-06-01 11:22:52,655 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT
- 2015-06-01 11:22:52,658 INFO [sqlalchemy.engine.base.Engine][MainThread] BEGIN (implicit)
- 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] INSERT INTO wikipages (title, body) VALUES (?, ?)
- 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] ('Root', '<p>Root</p>')
- 2015-06-01 11:22:52,659 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT
+ 2016-04-16 13:01:33,058 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
+ 2016-04-16 13:01:33,059 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT
+ 2016-04-16 13:01:33,062 INFO [sqlalchemy.engine.base.Engine][MainThread] BEGIN (implicit)
+ 2016-04-16 13:01:33,062 INFO [sqlalchemy.engine.base.Engine][MainThread] INSERT INTO wikipages (title, body) VALUES (?, ?)
+ 2016-04-16 13:01:33,063 INFO [sqlalchemy.engine.base.Engine][MainThread] ('Root', '<p>Root</p>')
+ 2016-04-16 13:01:33,063 INFO [sqlalchemy.engine.base.Engine][MainThread] COMMIT
-#. With our data now driven by SQLAlchemy queries, we need to update
- our ``databases/tutorial/views.py``:
+#. With our data now driven by SQLAlchemy queries, we need to update our
+ ``databases/tutorial/views.py``:
.. literalinclude:: databases/tutorial/views.py
:linenos:
-#. Our tests in ``databases/tutorial/tests.py`` changed to include
- SQLAlchemy bootstrapping:
+#. 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``:
+#. Run the tests in your package using ``py.test``:
- .. code-block:: bash
-
- $ $VENV/bin/nosetests tutorial
- ..
- -----------------------------------------------------------------
- Ran 2 tests in 1.141s
+ .. code-block:: bash
- OK
+ $ $VENV/bin/py.test tutorial/tests.py -q
+ ..
+ 2 passed in 1.41 seconds
#. Run your Pyramid application with:
@@ -144,57 +144,55 @@ Steps
#. 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?
+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
-application either as middleware or a Pyramid "tween". Then,
-just before you return the response, all transaction-aware parts of
-your application are executed.
+Specifically, you can install a transaction manager into your 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.
+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.
+``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 virtual environment'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``.
+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 virtual environment'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 of 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.
+dictionary-of-dictionaries data with proper database support: list the rows,
+add a row, edit a row, and delete a row.
+
-Extra Credit
+Extra credit
============
-#. Why all this code? Why can't I just type 2 lines and have magic ensue?
+#. Why all this code? Why can't I just type two lines and have magic ensue?
#. Give a try at a button that deletes a wiki page.
diff --git a/docs/quick_tutorial/databases/sqltutorial.sqlite b/docs/quick_tutorial/databases/sqltutorial.sqlite
deleted file mode 100644
index b8bd856fd..000000000
--- a/docs/quick_tutorial/databases/sqltutorial.sqlite
+++ /dev/null
Binary files differ