From 392cc17f5091d51a8e1b8908f8600c0b821ebd7f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 11 Nov 2015 21:58:03 -0800 Subject: basiclayout/tutorial - views - use package instead of single file - add tests.py from scaffold - update basiclayout.rst with views section --- docs/tutorials/wiki2/basiclayout.rst | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 8a1dbf3f8..cdcf0fa5f 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -116,17 +116,19 @@ Finally ``main`` is finished configuring things, so it uses the :lines: 21 :language: py -View declarations via ``views.py`` ----------------------------------- + +View declarations via the ``views`` package +------------------------------------------- The main function of a web framework is mapping each URL pattern to code (a :term:`view callable`) that is executed when the requested URL matches the corresponding :term:`route`. Our application uses the :meth:`pyramid.view.view_config` decorator to perform this mapping. -Open ``tutorial/tutorial/views.py``. It should already contain the following: +Open ``tutorial/tutorial/views/default.py`` in the ``views`` package. It +should already contain the following: - .. literalinclude:: src/basiclayout/tutorial/views.py + .. literalinclude:: src/basiclayout/tutorial/views/default.py :linenos: :language: py @@ -135,13 +137,13 @@ function it decorates (``my_view``) with a :term:`view configuration`, consisting of: * a ``route_name`` (``home``) - * a ``renderer``, which is a template from the ``templates`` subdirectory - of the package. + * a ``renderer``, which is a template from the ``templates`` subdirectory of + the package. When the pattern associated with the ``home`` view is matched during a request, -``my_view()`` will be executed. ``my_view()`` returns a dictionary; the -renderer will use the ``templates/mytemplate.pt`` template to create a response -based on the values in the dictionary. +``my_view()`` will be executed. ``my_view()`` returns a dictionary; the +renderer will use the ``templates/mytemplate.jinja2`` template to create a +response based on the values in the dictionary. Note that ``my_view()`` accepts a single argument named ``request``. This is the standard call signature for a Pyramid :term:`view callable`. @@ -154,13 +156,13 @@ application. Without being processed by ``scan``, the decorator effectively does nothing. ``@view_config`` is inert without being detected via a :term:`scan`. -The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:`` -clause to detect if there is a problem accessing the project database and -provide an alternate error response. That response will include the text -shown at the end of the file, which will be displayed in the browser to -inform the user about possible actions to take to solve the problem. +The sample ``my_view()`` created by the scaffold uses a ``try:`` and +``except:`` clause to detect if there is a problem accessing the project +database and provide an alternate error response. That response will include +the text shown at the end of the file, which will be displayed in the browser +to inform the user about possible actions to take to solve the problem. -Content Models with ``models.py`` +Content models with ``models.py`` --------------------------------- .. START moved from Application configuration with ``__init__.py``. This -- cgit v1.2.3 From 0409cf178d4c0fa9a0d3b0858ab2294935b23609 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 12 Nov 2015 00:40:02 -0800 Subject: basiclayout/tutorial - models, scripts, static, templates - use package instead of single file - add tests.py from scaffold - update basiclayout.rst with models section --- docs/tutorials/wiki2/basiclayout.rst | 117 ++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 56 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index cdcf0fa5f..5d9b62eea 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -113,7 +113,7 @@ Finally ``main`` is finished configuring things, so it uses the :term:`WSGI` application: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 21 + :lines: 13 :language: py @@ -162,94 +162,99 @@ database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser to inform the user about possible actions to take to solve the problem. -Content models with ``models.py`` ---------------------------------- +Content models with the ``models`` package +------------------------------------------ -.. START moved from Application configuration with ``__init__.py``. This - section is a WIP, and needs to be updated using the new models package. +In a SQLAlchemy-based application, a *model* object is an object composed by +querying the SQL database. The ``models`` package is where the ``alchemy`` +scaffold put the classes that implement our models. -The main function first creates a :term:`SQLAlchemy` database engine using -:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed -settings in the ``development.ini`` file's ``[app:main]`` section. -This will be a URI (something like ``sqlite://``): +First, open ``tutorial/tutorial/models/__init__.py``, which should already +contain the following: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 13 + .. literalinclude:: src/basiclayout/tutorial/models/__init__.py + :linenos: :language: py -``main`` then initializes our SQLAlchemy session object, passing it the -engine: +Our ``__init__.py`` will perform some imports to support later code, then calls +the function :func:`sqlalchemy.orm.configure_mappers`. - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 14 +Next open ``tutorial/tutorial/models/meta.py``, which should already contain +the following: + + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :linenos: :language: py -``main`` subsequently initializes our SQLAlchemy declarative ``Base`` object, -assigning the engine we created to the ``bind`` attribute of it's -``metadata`` object. This allows table definitions done imperatively -(instead of declaratively, via a class statement) to work. We won't use any -such tables in our application, but if you add one later, long after you've -forgotten about this tutorial, you won't be left scratching your head when it -doesn't work. +``meta.py`` contains imports that are used to support later code. We create a +dictionary ``NAMING_CONVENTION`` as well. - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 15 + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :end-before: metadata + :linenos: :language: py -.. END moved from Application configuration with ``__init__.py`` +Next we create a ``metadata`` object from the class +:class:`sqlalchemy.schema.MetaData`, using ``NAMING_CONVENTION`` as the value +for the ``naming_convention`` argument. We also need to create a declarative +``Base`` object to use as a base class for our model. Then our model classes +will inherit from the ``Base`` class so they can be associated with our +particular database connection. -In a SQLAlchemy-based application, a *model* object is an object composed by -querying the SQL database. The ``models.py`` file is where the ``alchemy`` -scaffold put the classes that implement our models. + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :lines: 15-16 + :lineno-start: 15 + :linenos: + :language: py -Open ``tutorial/tutorial/models.py``. It should already contain the following: +Next we define several functions, the first of which is ``includeme``, which +configures various database settings by calling subsequently defined functions. - .. literalinclude:: src/basiclayout/tutorial/models.py + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: includeme :linenos: :language: py -Let's examine this in detail. First, we need some imports to support later code: +The function ``get_session`` registers a database session with a transaction +manager, and returns a ``dbsession`` object. With the transaction manager, our +application will automatically issue a transaction commit after every request +unless an exception is raised, in which case the transaction will be aborted. - .. literalinclude:: src/basiclayout/tutorial/models.py - :end-before: DBSession + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_session :linenos: :language: py -Next we set up a SQLAlchemy ``DBSession`` object: +The ``get_engine`` function creates an :term:`SQLAlchemy` database engine using +:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.``-prefixed +settings in the ``development.ini`` file's ``[app:main]`` section, which is a +URI, something like ``sqlite://``. - .. literalinclude:: src/basiclayout/tutorial/models.py - :lines: 17 + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_engine + :linenos: :language: py -``scoped_session`` and ``sessionmaker`` are standard SQLAlchemy helpers. -``scoped_session`` allows us to access our database connection globally. -``sessionmaker`` creates a database session object. We pass to -``sessionmaker`` the ``extension=ZopeTransactionExtension()`` extension -option in order to allow the system to automatically manage database -transactions. With ``ZopeTransactionExtension`` activated, our application -will automatically issue a transaction commit after every request unless an -exception is raised, in which case the transaction will be aborted. - -We also need to create a declarative ``Base`` object to use as a -base class for our model: +The function ``get_dbmaker`` accepts an :term:`SQLAlchemy` database engine, +and creates a database session object ``dbmaker`` from the :term:`SQLAlchemy` +class :class:`sqlalchemy.orm.session.sessionmaker`, which is then used for +creating a session with the database engine. - .. literalinclude:: src/basiclayout/tutorial/models.py - :lines: 17 + .. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_dbmaker + :linenos: :language: py -Our model classes will inherit from this ``Base`` class so they can be -associated with our particular database connection. - -To give a simple example of a model class, we define one named ``MyModel``: +To give a simple example of a model class, we define one named ``MyModel``: - .. literalinclude:: src/basiclayout/tutorial/models.py + .. literalinclude:: src/basiclayout/tutorial/models/mymodel.py :pyobject: MyModel :linenos: :language: py Our example model does not require an ``__init__`` method because SQLAlchemy -supplies for us a default constructor if one is not already present, -which accepts keyword arguments of the same name as that of the mapped attributes. +supplies for us a default constructor if one is not already present, which +accepts keyword arguments of the same name as that of the mapped attributes. .. note:: Example usage of MyModel: -- cgit v1.2.3 From 1b994c6b87449a9542dcf5f0daf44023dbff31ff Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 12 Nov 2015 01:04:18 -0800 Subject: basiclayout/tutorial poke in attempt to resolve merge conflict on GitHub --- docs/tutorials/wiki2/basiclayout.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 5d9b62eea..c293f3170 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -162,6 +162,7 @@ database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser to inform the user about possible actions to take to solve the problem. + Content models with the ``models`` package ------------------------------------------ -- cgit v1.2.3 From 414b67b45bab156b9738105e180908c4eee8600a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 12 Nov 2015 12:56:27 -0600 Subject: Restore progress after backing changes out of master. This reverts commit 049e670aef9ea5611561546fd5c0e2dd6152b9b7. --- docs/tutorials/wiki2/basiclayout.rst | 98 ++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 43 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 649c11e85..abe9e4202 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -12,12 +12,12 @@ Application configuration with ``__init__.py`` A directory on disk can be turned into a Python :term:`package` by containing an ``__init__.py`` file. Even if empty, this marks a directory as a Python -package. We use ``__init__.py`` both as a marker, indicating the directory -in which it's contained is a package, and to contain application configuration +package. We use ``__init__.py`` both as a marker, indicating the directory in +which it's contained is a package, and to contain application configuration code. -Open ``tutorial/tutorial/__init__.py``. It should already contain -the following: +Open ``tutorial/tutorial/__init__.py``. It should already contain the +following: .. literalinclude:: src/basiclayout/tutorial/__init__.py :linenos: @@ -43,58 +43,37 @@ When you invoke the ``pserve development.ini`` command, the ``main`` function above is executed. It accepts some settings and returns a :term:`WSGI` application. (See :ref:`startup_chapter` for more about ``pserve``.) -The main function first creates a :term:`SQLAlchemy` database engine using -:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed -settings in the ``development.ini`` file's ``[app:main]`` section. -This will be a URI (something like ``sqlite://``): - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 13 - :language: py - -``main`` then initializes our SQLAlchemy session object, passing it the -engine: - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 14 - :language: py - -``main`` subsequently initializes our SQLAlchemy declarative ``Base`` object, -assigning the engine we created to the ``bind`` attribute of it's -``metadata`` object. This allows table definitions done imperatively -(instead of declaratively, via a class statement) to work. We won't use any -such tables in our application, but if you add one later, long after you've -forgotten about this tutorial, you won't be left scratching your head when it -doesn't work. - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 15 - :language: py - The next step of ``main`` is to construct a :term:`Configurator` object: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 16 + :lines: 7 :language: py ``settings`` is passed to the Configurator as a keyword argument with the dictionary values passed as the ``**settings`` argument. This will be a dictionary of settings parsed from the ``.ini`` file, which contains deployment-related values such as ``pyramid.reload_templates``, -``db_string``, etc. +``sqlalchemy.url``, and so on. -Next, include :term:`Chameleon` templating bindings so that we can use -renderers with the ``.pt`` extension within our project. +Next include :term:`Jinja2` templating bindings so that we can use renderers +with the ``.jinja2`` extension within our project. .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 17 + :lines: 8 + :language: py + +Next include the module ``meta`` from the package ``models`` using a dotted +Python path. + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 9 :language: py ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with two arguments: ``static`` (the name), and ``static`` (the path): .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 18 + :lines: 10 :language: py This registers a static resource view which will match any URL that starts @@ -112,11 +91,11 @@ via the :meth:`pyramid.config.Configurator.add_route` method that will be used when the URL is ``/``: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 19 + :lines: 11 :language: py -Since this route has a ``pattern`` equaling ``/`` it is the route that will -be matched when the URL ``/`` is visited, e.g. ``http://localhost:6543/``. +Since this route has a ``pattern`` equaling ``/``, it is the route that will +be matched when the URL ``/`` is visited, e.g., ``http://localhost:6543/``. ``main`` next calls the ``scan`` method of the configurator (:meth:`pyramid.config.Configurator.scan`), which will recursively scan our @@ -126,10 +105,10 @@ view configuration will be registered, which will allow one of our application URLs to be mapped to some code. .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 20 + :lines: 12 :language: py -Finally, ``main`` is finished configuring things, so it uses the +Finally ``main`` is finished configuring things, so it uses the :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a :term:`WSGI` application: @@ -187,6 +166,39 @@ to inform the user about possible actions to take to solve the problem. Content models with the ``models`` package ------------------------------------------ +.. START moved from Application configuration with ``__init__.py``. This + section is a WIP, and needs to be updated using the new models package. + +The main function first creates a :term:`SQLAlchemy` database engine using +:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed +settings in the ``development.ini`` file's ``[app:main]`` section. +This will be a URI (something like ``sqlite://``): + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 13 + :language: py + +``main`` then initializes our SQLAlchemy session object, passing it the +engine: + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 14 + :language: py + +``main`` subsequently initializes our SQLAlchemy declarative ``Base`` object, +assigning the engine we created to the ``bind`` attribute of it's +``metadata`` object. This allows table definitions done imperatively +(instead of declaratively, via a class statement) to work. We won't use any +such tables in our application, but if you add one later, long after you've +forgotten about this tutorial, you won't be left scratching your head when it +doesn't work. + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 15 + :language: py + +.. END moved from Application configuration with ``__init__.py`` + In a SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` scaffold put the classes that implement our models. -- cgit v1.2.3 From 3525fa106fe2ca4b4bed93e28f72b13e3fa943b3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 13 Nov 2015 03:54:14 -0800 Subject: correct line numbers in and remove obsolete WIP block wiki2/basiclayout.rst --- docs/tutorials/wiki2/basiclayout.rst | 45 ++++++++++-------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index abe9e4202..1ba7d3958 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -36,6 +36,7 @@ the ``main`` function we've defined in our ``__init__.py``: .. literalinclude:: src/basiclayout/tutorial/__init__.py :pyobject: main + :lineno-start: 4 :linenos: :language: py @@ -47,6 +48,7 @@ The next step of ``main`` is to construct a :term:`Configurator` object: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 7 + :lineno-start: 7 :language: py ``settings`` is passed to the Configurator as a keyword argument with the @@ -60,6 +62,7 @@ with the ``.jinja2`` extension within our project. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 8 + :lineno-start: 8 :language: py Next include the module ``meta`` from the package ``models`` using a dotted @@ -67,6 +70,7 @@ Python path. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 9 + :lineno-start: 9 :language: py ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with @@ -74,6 +78,7 @@ two arguments: ``static`` (the name), and ``static`` (the path): .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 10 + :lineno-start: 10 :language: py This registers a static resource view which will match any URL that starts @@ -92,6 +97,7 @@ used when the URL is ``/``: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 11 + :lineno-start: 11 :language: py Since this route has a ``pattern`` equaling ``/``, it is the route that will @@ -106,6 +112,7 @@ application URLs to be mapped to some code. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 12 + :lineno-start: 12 :language: py Finally ``main`` is finished configuring things, so it uses the @@ -114,6 +121,7 @@ Finally ``main`` is finished configuring things, so it uses the .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 13 + :lineno-start: 13 :language: py @@ -166,39 +174,6 @@ to inform the user about possible actions to take to solve the problem. Content models with the ``models`` package ------------------------------------------ -.. START moved from Application configuration with ``__init__.py``. This - section is a WIP, and needs to be updated using the new models package. - -The main function first creates a :term:`SQLAlchemy` database engine using -:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed -settings in the ``development.ini`` file's ``[app:main]`` section. -This will be a URI (something like ``sqlite://``): - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 13 - :language: py - -``main`` then initializes our SQLAlchemy session object, passing it the -engine: - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 14 - :language: py - -``main`` subsequently initializes our SQLAlchemy declarative ``Base`` object, -assigning the engine we created to the ``bind`` attribute of it's -``metadata`` object. This allows table definitions done imperatively -(instead of declaratively, via a class statement) to work. We won't use any -such tables in our application, but if you add one later, long after you've -forgotten about this tutorial, you won't be left scratching your head when it -doesn't work. - - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 15 - :language: py - -.. END moved from Application configuration with ``__init__.py`` - In a SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` scaffold put the classes that implement our models. @@ -246,6 +221,7 @@ configures various database settings by calling subsequently defined functions. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: includeme + :lineno-start: 19 :linenos: :language: py @@ -256,6 +232,7 @@ unless an exception is raised, in which case the transaction will be aborted. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_session + :lineno-start: 32 :linenos: :language: py @@ -266,6 +243,7 @@ URI, something like ``sqlite://``. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_engine + :lineno-start: 39 :linenos: :language: py @@ -276,6 +254,7 @@ creating a session with the database engine. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_dbmaker + :lineno-start: 43 :linenos: :language: py -- cgit v1.2.3 From 2f6864759d66b8a9cea845d8e6b628b5bede5336 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 14 Nov 2015 03:15:59 -0800 Subject: minor changes to narrative flow --- docs/tutorials/wiki2/basiclayout.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 1ba7d3958..1426e55a5 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -44,7 +44,7 @@ When you invoke the ``pserve development.ini`` command, the ``main`` function above is executed. It accepts some settings and returns a :term:`WSGI` application. (See :ref:`startup_chapter` for more about ``pserve``.) -The next step of ``main`` is to construct a :term:`Configurator` object: +Next in ``main``, construct a :term:`Configurator` object: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 7 @@ -279,8 +279,8 @@ The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. -The Index import and the Index object creation is not required for this -tutorial, and will be removed in the next step. - That's about all there is to it regarding models, views, and initialization code in our stock application. + +The Index import and the Index object creation is not required for this +tutorial, and will be removed in the next step. -- cgit v1.2.3 From 86d90fb8c22a50e68077542d8f3f0f488e72a5d8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 2 Dec 2015 04:38:58 -0800 Subject: - adjust linenos for NAMING_CONVENTION comment --- docs/tutorials/wiki2/basiclayout.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 1426e55a5..e3d0a0a3c 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -211,8 +211,8 @@ will inherit from the ``Base`` class so they can be associated with our particular database connection. .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :lines: 15-16 - :lineno-start: 15 + :lines: 18-19 + :lineno-start: 18 :linenos: :language: py @@ -221,7 +221,7 @@ configures various database settings by calling subsequently defined functions. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: includeme - :lineno-start: 19 + :lineno-start: 22 :linenos: :language: py @@ -232,7 +232,7 @@ unless an exception is raised, in which case the transaction will be aborted. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_session - :lineno-start: 32 + :lineno-start: 35 :linenos: :language: py @@ -243,7 +243,7 @@ URI, something like ``sqlite://``. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_engine - :lineno-start: 39 + :lineno-start: 42 :linenos: :language: py @@ -254,7 +254,7 @@ creating a session with the database engine. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :pyobject: get_dbmaker - :lineno-start: 43 + :lineno-start: 46 :linenos: :language: py -- cgit v1.2.3 From 8ec0b01ef0de3d7859e081652ef752d9af612fc5 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 5 Feb 2016 00:04:23 -0600 Subject: unindent literalincludes --- docs/tutorials/wiki2/basiclayout.rst | 166 +++++++++++++++++------------------ 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index e3d0a0a3c..d55ce807f 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -19,25 +19,25 @@ code. Open ``tutorial/tutorial/__init__.py``. It should already contain the following: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :linenos: + :language: py Let's go over this piece-by-piece. First, we need some imports to support later code: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :end-before: main - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :end-before: main + :linenos: + :language: py ``__init__.py`` defines a function named ``main``. Here is the entirety of the ``main`` function we've defined in our ``__init__.py``: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :pyobject: main - :lineno-start: 4 - :linenos: +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :pyobject: main + :lineno-start: 4 + :linenos: :language: py When you invoke the ``pserve development.ini`` command, the ``main`` function @@ -46,10 +46,10 @@ application. (See :ref:`startup_chapter` for more about ``pserve``.) Next in ``main``, construct a :term:`Configurator` object: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 7 - :lineno-start: 7 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 7 + :lineno-start: 7 + :language: py ``settings`` is passed to the Configurator as a keyword argument with the dictionary values passed as the ``**settings`` argument. This will be a @@ -60,26 +60,26 @@ deployment-related values such as ``pyramid.reload_templates``, Next include :term:`Jinja2` templating bindings so that we can use renderers with the ``.jinja2`` extension within our project. - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 8 - :lineno-start: 8 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 8 + :lineno-start: 8 + :language: py Next include the module ``meta`` from the package ``models`` using a dotted Python path. - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 9 - :lineno-start: 9 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 9 + :lineno-start: 9 + :language: py ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with two arguments: ``static`` (the name), and ``static`` (the path): - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 10 - :lineno-start: 10 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 10 + :lineno-start: 10 + :language: py This registers a static resource view which will match any URL that starts with the prefix ``/static`` (by virtue of the first argument to @@ -95,10 +95,10 @@ Using the configurator ``main`` also registers a :term:`route configuration` via the :meth:`pyramid.config.Configurator.add_route` method that will be used when the URL is ``/``: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 11 - :lineno-start: 11 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 11 + :lineno-start: 11 + :language: py Since this route has a ``pattern`` equaling ``/``, it is the route that will be matched when the URL ``/`` is visited, e.g., ``http://localhost:6543/``. @@ -110,19 +110,19 @@ other special) decorators. When it finds a ``@view_config`` decorator, a view configuration will be registered, which will allow one of our application URLs to be mapped to some code. - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 12 - :lineno-start: 12 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 12 + :lineno-start: 12 + :language: py Finally ``main`` is finished configuring things, so it uses the :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a :term:`WSGI` application: - .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 13 - :lineno-start: 13 - :language: py +.. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 13 + :lineno-start: 13 + :language: py View declarations via the ``views`` package @@ -136,9 +136,9 @@ corresponding :term:`route`. Our application uses the Open ``tutorial/tutorial/views/default.py`` in the ``views`` package. It should already contain the following: - .. literalinclude:: src/basiclayout/tutorial/views/default.py - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/views/default.py + :linenos: + :language: py The important part here is that the ``@view_config`` decorator associates the function it decorates (``my_view``) with a :term:`view configuration`, @@ -181,9 +181,9 @@ scaffold put the classes that implement our models. First, open ``tutorial/tutorial/models/__init__.py``, which should already contain the following: - .. literalinclude:: src/basiclayout/tutorial/models/__init__.py - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py + :linenos: + :language: py Our ``__init__.py`` will perform some imports to support later code, then calls the function :func:`sqlalchemy.orm.configure_mappers`. @@ -191,17 +191,17 @@ the function :func:`sqlalchemy.orm.configure_mappers`. Next open ``tutorial/tutorial/models/meta.py``, which should already contain the following: - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :linenos: + :language: py ``meta.py`` contains imports that are used to support later code. We create a dictionary ``NAMING_CONVENTION`` as well. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :end-before: metadata - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :end-before: metadata + :linenos: + :language: py Next we create a ``metadata`` object from the class :class:`sqlalchemy.schema.MetaData`, using ``NAMING_CONVENTION`` as the value @@ -210,60 +210,60 @@ for the ``naming_convention`` argument. We also need to create a declarative will inherit from the ``Base`` class so they can be associated with our particular database connection. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :lines: 18-19 - :lineno-start: 18 - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :lines: 18-19 + :lineno-start: 18 + :linenos: + :language: py Next we define several functions, the first of which is ``includeme``, which configures various database settings by calling subsequently defined functions. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: includeme - :lineno-start: 22 - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: includeme + :lineno-start: 22 + :linenos: + :language: py The function ``get_session`` registers a database session with a transaction manager, and returns a ``dbsession`` object. With the transaction manager, our application will automatically issue a transaction commit after every request unless an exception is raised, in which case the transaction will be aborted. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: get_session - :lineno-start: 35 - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_session + :lineno-start: 35 + :linenos: + :language: py The ``get_engine`` function creates an :term:`SQLAlchemy` database engine using :func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.``-prefixed settings in the ``development.ini`` file's ``[app:main]`` section, which is a URI, something like ``sqlite://``. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: get_engine - :lineno-start: 42 - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_engine + :lineno-start: 42 + :linenos: + :language: py The function ``get_dbmaker`` accepts an :term:`SQLAlchemy` database engine, and creates a database session object ``dbmaker`` from the :term:`SQLAlchemy` class :class:`sqlalchemy.orm.session.sessionmaker`, which is then used for creating a session with the database engine. - .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: get_dbmaker - :lineno-start: 46 - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/meta.py + :pyobject: get_dbmaker + :lineno-start: 46 + :linenos: + :language: py To give a simple example of a model class, we define one named ``MyModel``: - .. literalinclude:: src/basiclayout/tutorial/models/mymodel.py - :pyobject: MyModel - :linenos: - :language: py +.. literalinclude:: src/basiclayout/tutorial/models/mymodel.py + :pyobject: MyModel + :linenos: + :language: py Our example model does not require an ``__init__`` method because SQLAlchemy supplies for us a default constructor if one is not already present, which @@ -282,5 +282,5 @@ class. That's about all there is to it regarding models, views, and initialization code in our stock application. -The Index import and the Index object creation is not required for this -tutorial, and will be removed in the next step. +The ``Index`` import and the ``Index`` object creation is not required for +this tutorial, and will be removed in the next step. -- cgit v1.2.3 From 7b89a7e435b9edb4da6976e9185ae425717d4085 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 5 Feb 2016 01:00:49 -0600 Subject: update basiclayout prose --- docs/tutorials/wiki2/basiclayout.rst | 168 ++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 70 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index d55ce807f..976f12e90 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -29,6 +29,7 @@ later code: .. literalinclude:: src/basiclayout/tutorial/__init__.py :end-before: main :linenos: + :lineno-match: :language: py ``__init__.py`` defines a function named ``main``. Here is the entirety of @@ -36,9 +37,9 @@ the ``main`` function we've defined in our ``__init__.py``: .. literalinclude:: src/basiclayout/tutorial/__init__.py :pyobject: main - :lineno-start: 4 :linenos: - :language: py + :lineno-match: + :language: py When you invoke the ``pserve development.ini`` command, the ``main`` function above is executed. It accepts some settings and returns a :term:`WSGI` @@ -48,7 +49,7 @@ Next in ``main``, construct a :term:`Configurator` object: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 7 - :lineno-start: 7 + :lineno-match: :language: py ``settings`` is passed to the Configurator as a keyword argument with the @@ -62,15 +63,15 @@ with the ``.jinja2`` extension within our project. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 8 - :lineno-start: 8 + :lineno-match: :language: py -Next include the module ``meta`` from the package ``models`` using a dotted -Python path. +Next include the the package ``models`` using a dotted Python path. The +exact setup of the models will be covered later. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 9 - :lineno-start: 9 + :lineno-match: :language: py ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with @@ -78,7 +79,7 @@ two arguments: ``static`` (the name), and ``static`` (the path): .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 10 - :lineno-start: 10 + :lineno-match: :language: py This registers a static resource view which will match any URL that starts @@ -97,7 +98,7 @@ used when the URL is ``/``: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 11 - :lineno-start: 11 + :lineno-match: :language: py Since this route has a ``pattern`` equaling ``/``, it is the route that will @@ -112,7 +113,7 @@ application URLs to be mapped to some code. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 12 - :lineno-start: 12 + :lineno-match: :language: py Finally ``main`` is finished configuring things, so it uses the @@ -178,25 +179,16 @@ In a SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` scaffold put the classes that implement our models. -First, open ``tutorial/tutorial/models/__init__.py``, which should already -contain the following: - -.. literalinclude:: src/basiclayout/tutorial/models/__init__.py - :linenos: - :language: py - -Our ``__init__.py`` will perform some imports to support later code, then calls -the function :func:`sqlalchemy.orm.configure_mappers`. - -Next open ``tutorial/tutorial/models/meta.py``, which should already contain +First, open ``tutorial/tutorial/models/meta.py``, which should already contain the following: .. literalinclude:: src/basiclayout/tutorial/models/meta.py :linenos: :language: py -``meta.py`` contains imports that are used to support later code. We create a -dictionary ``NAMING_CONVENTION`` as well. +``meta.py`` contains imports and support code for defining the models. We +create a dictionary ``NAMING_CONVENTION`` as well for consistent naming of +support objects like indices and constraints. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :end-before: metadata @@ -205,82 +197,118 @@ dictionary ``NAMING_CONVENTION`` as well. Next we create a ``metadata`` object from the class :class:`sqlalchemy.schema.MetaData`, using ``NAMING_CONVENTION`` as the value -for the ``naming_convention`` argument. We also need to create a declarative -``Base`` object to use as a base class for our model. Then our model classes -will inherit from the ``Base`` class so they can be associated with our -particular database connection. +for the ``naming_convention`` argument. + +A ``MetaData`` object represents the table and other schema definitions for +a single database. We also need to create a declarative ``Base`` object to use +as a base class for our models. Our models will inherit from this ``Base`` +which will attach the tables to the ``metadata`` we created and define our +application's database schema. .. literalinclude:: src/basiclayout/tutorial/models/meta.py - :lines: 18-19 - :lineno-start: 18 + :lines: 15-16 + :lineno-match: :linenos: :language: py -Next we define several functions, the first of which is ``includeme``, which -configures various database settings by calling subsequently defined functions. +We've defined the ``models`` as a packge to make it straightforward to +define models separately in different modules. To give a simple example of a +model class, we define one named ``MyModel`` in a ``mymodel.py``: -.. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: includeme - :lineno-start: 22 +.. literalinclude:: src/basiclayout/tutorial/models/mymodel.py + :pyobject: MyModel :linenos: :language: py -The function ``get_session`` registers a database session with a transaction -manager, and returns a ``dbsession`` object. With the transaction manager, our -application will automatically issue a transaction commit after every request -unless an exception is raised, in which case the transaction will be aborted. +Our example model does not require an ``__init__`` method because SQLAlchemy +supplies for us a default constructor if one is not already present, which +accepts keyword arguments of the same name as that of the mapped attributes. -.. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: get_session - :lineno-start: 35 +.. note:: Example usage of MyModel: + + .. code-block:: python + + johnny = MyModel(name="John Doe", value=10) + +The ``MyModel`` class has a ``__tablename__`` attribute. This informs +SQLAlchemy which table to use to store the data representing instances of this +class. + +Finally, open ``tutorial/tutorial/models/__init__.py``, which should already +contain the following: + +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py :linenos: :language: py -The ``get_engine`` function creates an :term:`SQLAlchemy` database engine using -:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.``-prefixed -settings in the ``development.ini`` file's ``[app:main]`` section, which is a -URI, something like ``sqlite://``. +Our ``models/__init__.py`` module defines the primary API we will use for +configuring the database connections within our application and it contains +several functions we will cover below. + +As we mentioned above, the purpose of the ``models.meta.metadata`` object is +to describe the schema of the database and this is done by defining models +that inherit from the ``Base`` attached to that ``metadata`` object. In +Python, code is only executed if it is imported and so to attach the +``models`` table, defined in ``mymodel.py`` to the ``metadata`` we must +import it. If we skip this step then later when we run ``metadata.create_all`` +the table will not be created because the ``metadata`` does not know about it! +Another important reason to import all of the models is that when +defining relationships between models they must all exist in order for +SQLAlchemy to find and build those internal mappings. This is why after +importing all the models we explicitly execute the function +:func:`sqlalchemy.orm.configure_mappers`, once we are sure all the models have +been defined and before we start creating connections. + +Next we define several functions for connecting to our database. The first +and lowest level is the ``get_engine`` function which creates an +:term:`SQLAlchemy` database engine using :func:`sqlalchemy.engine_from_config` +from the ``sqlalchemy.``-prefixed settings in the ``development.ini`` +file's ``[app:main]`` section, which is a URI (something like ``sqlite://``). -.. literalinclude:: src/basiclayout/tutorial/models/meta.py +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_engine - :lineno-start: 42 + :lineno-match: :linenos: :language: py -The function ``get_dbmaker`` accepts an :term:`SQLAlchemy` database engine, -and creates a database session object ``dbmaker`` from the :term:`SQLAlchemy` +The function ``get_session_factory`` accepts an :term:`SQLAlchemy` database +engine, and creates a ``session_factory`` from the :term:`SQLAlchemy` class :class:`sqlalchemy.orm.session.sessionmaker`, which is then used for -creating a session with the database engine. +creating sessions bound to the database engine. -.. literalinclude:: src/basiclayout/tutorial/models/meta.py - :pyobject: get_dbmaker - :lineno-start: 46 +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py + :pyobject: get_session_factory + :lineno-match: :linenos: :language: py -To give a simple example of a model class, we define one named ``MyModel``: +The function ``get_tm_session`` registers a database session with a transaction +manager, and returns a ``dbsession`` object. With the transaction manager, our +application will automatically issue a transaction commit after every request +unless an exception is raised, in which case the transaction will be aborted. -.. literalinclude:: src/basiclayout/tutorial/models/mymodel.py - :pyobject: MyModel +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py + :pyobject: get_tm_session + :lineno-match: :linenos: :language: py -Our example model does not require an ``__init__`` method because SQLAlchemy -supplies for us a default constructor if one is not already present, which -accepts keyword arguments of the same name as that of the mapped attributes. - -.. note:: Example usage of MyModel: - - .. code-block:: python - - johnny = MyModel(name="John Doe", value=10) +Finally, we define an ``includeme`` function, which is a hook for use with +:meth:`pyramid.config.Configurator.include` to activate code in a Pyramid +application addon. It is the code that is executed above when we ran +``config.include('.models')`` in our application's ``main`` function. This +function will take the settings from the application, create an engine +and define a ``request.dbsession`` property which we can use to do work +on behalf of an incoming request to our application. -The ``MyModel`` class has a ``__tablename__`` attribute. This informs -SQLAlchemy which table to use to store the data representing instances of this -class. +.. literalinclude:: src/basiclayout/tutorial/models/__init__.py + :pyobject: includeme + :lineno-match: + :linenos: + :language: py That's about all there is to it regarding models, views, and initialization code in our stock application. -The ``Index`` import and the ``Index`` object creation is not required for -this tutorial, and will be removed in the next step. +The ``Index`` import and the ``Index`` object creation in ``mymodel.py`` is +not required for this tutorial, and will be removed in the next step. -- cgit v1.2.3 From 21d69fd97b66401264746bb7dad1e8d4bd2491b9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 5 Feb 2016 01:09:11 -0600 Subject: link to create_all sqla method --- docs/tutorials/wiki2/basiclayout.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 976f12e90..6d1ff73a0 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -250,8 +250,10 @@ to describe the schema of the database and this is done by defining models that inherit from the ``Base`` attached to that ``metadata`` object. In Python, code is only executed if it is imported and so to attach the ``models`` table, defined in ``mymodel.py`` to the ``metadata`` we must -import it. If we skip this step then later when we run ``metadata.create_all`` -the table will not be created because the ``metadata`` does not know about it! +import it. If we skip this step then later when we run +:meth:`sqlalchemy.schema.MetaData.create_all` the table will not be created +because the ``metadata`` does not know about it! + Another important reason to import all of the models is that when defining relationships between models they must all exist in order for SQLAlchemy to find and build those internal mappings. This is why after -- cgit v1.2.3 From ab68f1f89a0a1602078bf1a99741d0635ce06dd0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 5 Feb 2016 01:28:18 -0800 Subject: minor grammar and punctuation tweaks, break up run-on sentences. --- docs/tutorials/wiki2/basiclayout.rst | 50 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 6d1ff73a0..3533bb455 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -201,8 +201,8 @@ for the ``naming_convention`` argument. A ``MetaData`` object represents the table and other schema definitions for a single database. We also need to create a declarative ``Base`` object to use -as a base class for our models. Our models will inherit from this ``Base`` -which will attach the tables to the ``metadata`` we created and define our +as a base class for our models. Our models will inherit from this ``Base``, +which will attach the tables to the ``metadata`` we created, and define our application's database schema. .. literalinclude:: src/basiclayout/tutorial/models/meta.py @@ -242,30 +242,30 @@ contain the following: :language: py Our ``models/__init__.py`` module defines the primary API we will use for -configuring the database connections within our application and it contains +configuring the database connections within our application, and it contains several functions we will cover below. As we mentioned above, the purpose of the ``models.meta.metadata`` object is -to describe the schema of the database and this is done by defining models -that inherit from the ``Base`` attached to that ``metadata`` object. In -Python, code is only executed if it is imported and so to attach the -``models`` table, defined in ``mymodel.py`` to the ``metadata`` we must -import it. If we skip this step then later when we run -:meth:`sqlalchemy.schema.MetaData.create_all` the table will not be created +to describe the schema of the database. This is done by defining models that +inherit from the ``Base`` attached to that ``metadata`` object. In Python, code +is only executed if it is imported, and so to attach the ``models`` table +defined in ``mymodel.py`` to the ``metadata``, we must import it. If we skip +this step, then later, when we run +:meth:`sqlalchemy.schema.MetaData.create_all`, the table will not be created because the ``metadata`` does not know about it! -Another important reason to import all of the models is that when -defining relationships between models they must all exist in order for -SQLAlchemy to find and build those internal mappings. This is why after -importing all the models we explicitly execute the function +Another important reason to import all of the models is that, when defining +relationships between models, they must all exist in order for SQLAlchemy to +find and build those internal mappings. This is why, after importing all the +models, we explicitly execute the function :func:`sqlalchemy.orm.configure_mappers`, once we are sure all the models have been defined and before we start creating connections. -Next we define several functions for connecting to our database. The first -and lowest level is the ``get_engine`` function which creates an -:term:`SQLAlchemy` database engine using :func:`sqlalchemy.engine_from_config` -from the ``sqlalchemy.``-prefixed settings in the ``development.ini`` -file's ``[app:main]`` section, which is a URI (something like ``sqlite://``). +Next we define several functions for connecting to our database. The first and +lowest level is the ``get_engine`` function. This creates an :term:`SQLAlchemy` +database engine using :func:`sqlalchemy.engine_from_config` from the +``sqlalchemy.``-prefixed settings in the ``development.ini`` file's +``[app:main]`` section. This setting is a URI (something like ``sqlite://``). .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_engine @@ -274,9 +274,9 @@ file's ``[app:main]`` section, which is a URI (something like ``sqlite://``). :language: py The function ``get_session_factory`` accepts an :term:`SQLAlchemy` database -engine, and creates a ``session_factory`` from the :term:`SQLAlchemy` -class :class:`sqlalchemy.orm.session.sessionmaker`, which is then used for -creating sessions bound to the database engine. +engine, and creates a ``session_factory`` from the :term:`SQLAlchemy` class +:class:`sqlalchemy.orm.session.sessionmaker`. This ``session_factory`` is then +used for creating sessions bound to the database engine. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_session_factory @@ -286,7 +286,7 @@ creating sessions bound to the database engine. The function ``get_tm_session`` registers a database session with a transaction manager, and returns a ``dbsession`` object. With the transaction manager, our -application will automatically issue a transaction commit after every request +application will automatically issue a transaction commit after every request, unless an exception is raised, in which case the transaction will be aborted. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py @@ -297,10 +297,10 @@ unless an exception is raised, in which case the transaction will be aborted. Finally, we define an ``includeme`` function, which is a hook for use with :meth:`pyramid.config.Configurator.include` to activate code in a Pyramid -application addon. It is the code that is executed above when we ran +application add-on. It is the code that is executed above when we ran ``config.include('.models')`` in our application's ``main`` function. This -function will take the settings from the application, create an engine -and define a ``request.dbsession`` property which we can use to do work +function will take the settings from the application, create an engine, +and define a ``request.dbsession`` property, which we can use to do work on behalf of an incoming request to our application. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py -- cgit v1.2.3 From d1cb34643e086ac74965455b486ce0058764324f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 7 Feb 2016 13:57:51 -0600 Subject: assume the user is in the tutorial folder this is already assumed inside of installation where commands are run relative to setup.py --- docs/tutorials/wiki2/basiclayout.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 6d1ff73a0..eb315d2cb 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -16,7 +16,7 @@ package. We use ``__init__.py`` both as a marker, indicating the directory in which it's contained is a package, and to contain application configuration code. -Open ``tutorial/tutorial/__init__.py``. It should already contain the +Open ``tutorial/__init__.py``. It should already contain the following: .. literalinclude:: src/basiclayout/tutorial/__init__.py @@ -134,7 +134,7 @@ The main function of a web framework is mapping each URL pattern to code (a corresponding :term:`route`. Our application uses the :meth:`pyramid.view.view_config` decorator to perform this mapping. -Open ``tutorial/tutorial/views/default.py`` in the ``views`` package. It +Open ``tutorial/views/default.py`` in the ``views`` package. It should already contain the following: .. literalinclude:: src/basiclayout/tutorial/views/default.py @@ -179,7 +179,7 @@ In a SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` scaffold put the classes that implement our models. -First, open ``tutorial/tutorial/models/meta.py``, which should already contain +First, open ``tutorial/models/meta.py``, which should already contain the following: .. literalinclude:: src/basiclayout/tutorial/models/meta.py @@ -234,7 +234,7 @@ The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. -Finally, open ``tutorial/tutorial/models/__init__.py``, which should already +Finally, open ``tutorial/models/__init__.py``, which should already contain the following: .. literalinclude:: src/basiclayout/tutorial/models/__init__.py -- cgit v1.2.3 From da5ebc28c38ea32ad99389b5bc23e2f847af8047 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 14 Feb 2016 17:40:03 -0600 Subject: split routes into a separate module --- docs/tutorials/wiki2/basiclayout.rst | 64 ++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 485d38047..1ae51eb93 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -74,35 +74,19 @@ exact setup of the models will be covered later. :lineno-match: :language: py -``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with -two arguments: ``static`` (the name), and ``static`` (the path): +Next include the ``routes`` module using a dotted Python path. This module +will be explained in the next section. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 10 :lineno-match: :language: py -This registers a static resource view which will match any URL that starts -with the prefix ``/static`` (by virtue of the first argument to -``add_static_view``). This will serve up static resources for us from within -the ``static`` directory of our ``tutorial`` package, in this case, via -``http://localhost:6543/static/`` and below (by virtue of the second argument -to ``add_static_view``). With this declaration, we're saying that any URL that -starts with ``/static`` should go to the static view; any remainder of its -path (e.g. the ``/foo`` in ``/static/foo``) will be used to compose a path to -a static file resource, such as a CSS file. - -Using the configurator ``main`` also registers a :term:`route configuration` -via the :meth:`pyramid.config.Configurator.add_route` method that will be -used when the URL is ``/``: - -.. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 11 - :lineno-match: - :language: py +.. note:: -Since this route has a ``pattern`` equaling ``/``, it is the route that will -be matched when the URL ``/`` is visited, e.g., ``http://localhost:6543/``. + Pyramid's :meth:`pyramid.config.Configurator.include` method is the + primary mechanism for extending the configurator and breaking your code + into feature-focused modules. ``main`` next calls the ``scan`` method of the configurator (:meth:`pyramid.config.Configurator.scan`), which will recursively scan our @@ -112,7 +96,7 @@ view configuration will be registered, which will allow one of our application URLs to be mapped to some code. .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 12 + :lines: 11 :lineno-match: :language: py @@ -121,11 +105,41 @@ Finally ``main`` is finished configuring things, so it uses the :term:`WSGI` application: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 13 - :lineno-start: 13 + :lines: 12 + :lineno-match: :language: py +Route declarations +------------------ + +Open the ``tutorials/routes.py`` file. It should already contain the +following: + +.. literalinclude:: src/basiclayout/tutorial/routes.py + :linenos: + :language: py + +First, on line 2, call :meth:`pyramid.config.Configurator.add_static_view` +with two arguments: ``static`` (the name), and ``static`` (the path). + +This registers a static resource view which will match any URL that starts +with the prefix ``/static`` (by virtue of the first argument to +``add_static_view``). This will serve up static resources for us from within +the ``static`` directory of our ``tutorial`` package, in this case, via +``http://localhost:6543/static/`` and below (by virtue of the second argument +to ``add_static_view``). With this declaration, we're saying that any URL that +starts with ``/static`` should go to the static view; any remainder of its +path (e.g. the ``/foo`` in ``/static/foo``) will be used to compose a path to +a static file resource, such as a CSS file. + +Second, on line 3, the module registers a :term:`route configuration` +via the :meth:`pyramid.config.Configurator.add_route` method that will be +used when the URL is ``/``. Since this route has a ``pattern`` equaling +``/``, it is the route that will be matched when the URL ``/`` is visited, +e.g., ``http://localhost:6543/``. + + View declarations via the ``views`` package ------------------------------------------- -- cgit v1.2.3 From 4f87e545ed9596b9be5ca5958e80be55dba28a87 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 22 Feb 2016 00:58:03 -0800 Subject: update basiclayout - minor grammar and syntax - insert complete mymodel.py code --- docs/tutorials/wiki2/basiclayout.rst | 126 ++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 60 deletions(-) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 1ae51eb93..1310e0969 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -16,15 +16,14 @@ package. We use ``__init__.py`` both as a marker, indicating the directory in which it's contained is a package, and to contain application configuration code. -Open ``tutorial/__init__.py``. It should already contain the -following: +Open ``tutorial/__init__.py``. It should already contain the following: .. literalinclude:: src/basiclayout/tutorial/__init__.py :linenos: :language: py -Let's go over this piece-by-piece. First, we need some imports to support -later code: +Let's go over this piece-by-piece. First we need some imports to support later +code: .. literalinclude:: src/basiclayout/tutorial/__init__.py :end-before: main @@ -52,10 +51,10 @@ Next in ``main``, construct a :term:`Configurator` object: :lineno-match: :language: py -``settings`` is passed to the Configurator as a keyword argument with the -dictionary values passed as the ``**settings`` argument. This will be a +``settings`` is passed to the ``Configurator`` as a keyword argument with the +dictionary values passed as the ``**settings`` argument. This will be a dictionary of settings parsed from the ``.ini`` file, which contains -deployment-related values such as ``pyramid.reload_templates``, +deployment-related values, such as ``pyramid.reload_templates``, ``sqlalchemy.url``, and so on. Next include :term:`Jinja2` templating bindings so that we can use renderers @@ -66,16 +65,16 @@ with the ``.jinja2`` extension within our project. :lineno-match: :language: py -Next include the the package ``models`` using a dotted Python path. The -exact setup of the models will be covered later. +Next include the the package ``models`` using a dotted Python path. The exact +setup of the models will be covered later. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 9 :lineno-match: :language: py -Next include the ``routes`` module using a dotted Python path. This module -will be explained in the next section. +Next include the ``routes`` module using a dotted Python path. This module will +be explained in the next section. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 10 @@ -84,16 +83,16 @@ will be explained in the next section. .. note:: - Pyramid's :meth:`pyramid.config.Configurator.include` method is the - primary mechanism for extending the configurator and breaking your code - into feature-focused modules. + Pyramid's :meth:`pyramid.config.Configurator.include` method is the primary + mechanism for extending the configurator and breaking your code into + feature-focused modules. ``main`` next calls the ``scan`` method of the configurator (:meth:`pyramid.config.Configurator.scan`), which will recursively scan our -``tutorial`` package, looking for ``@view_config`` (and -other special) decorators. When it finds a ``@view_config`` decorator, a -view configuration will be registered, which will allow one of our -application URLs to be mapped to some code. +``tutorial`` package, looking for ``@view_config`` and other special +decorators. When it finds a ``@view_config`` decorator, a view configuration +will be registered, allowing one of our application URLs to be mapped to some +code. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 11 @@ -113,31 +112,31 @@ Finally ``main`` is finished configuring things, so it uses the Route declarations ------------------ -Open the ``tutorials/routes.py`` file. It should already contain the -following: +Open the ``tutorials/routes.py`` file. It should already contain the following: .. literalinclude:: src/basiclayout/tutorial/routes.py :linenos: :language: py -First, on line 2, call :meth:`pyramid.config.Configurator.add_static_view` -with two arguments: ``static`` (the name), and ``static`` (the path). +On line 2, we call :meth:`pyramid.config.Configurator.add_static_view` with +three arguments: ``static`` (the name), ``static`` (the path), and +``cache_max_age`` (a keyword argument). This registers a static resource view which will match any URL that starts with the prefix ``/static`` (by virtue of the first argument to -``add_static_view``). This will serve up static resources for us from within -the ``static`` directory of our ``tutorial`` package, in this case, via +``add_static_view``). This will serve up static resources for us from within +the ``static`` directory of our ``tutorial`` package, in this case via ``http://localhost:6543/static/`` and below (by virtue of the second argument to ``add_static_view``). With this declaration, we're saying that any URL that starts with ``/static`` should go to the static view; any remainder of its -path (e.g. the ``/foo`` in ``/static/foo``) will be used to compose a path to +path (e.g., the ``/foo`` in ``/static/foo``) will be used to compose a path to a static file resource, such as a CSS file. -Second, on line 3, the module registers a :term:`route configuration` -via the :meth:`pyramid.config.Configurator.add_route` method that will be -used when the URL is ``/``. Since this route has a ``pattern`` equaling -``/``, it is the route that will be matched when the URL ``/`` is visited, -e.g., ``http://localhost:6543/``. +On line 3, the module registers a :term:`route configuration` via the +:meth:`pyramid.config.Configurator.add_route` method that will be used when the +URL is ``/``. Since this route has a ``pattern`` equaling ``/``, it is the +route that will be matched when the URL ``/`` is visited, e.g., +``http://localhost:6543/``. View declarations via the ``views`` package @@ -148,15 +147,15 @@ The main function of a web framework is mapping each URL pattern to code (a corresponding :term:`route`. Our application uses the :meth:`pyramid.view.view_config` decorator to perform this mapping. -Open ``tutorial/views/default.py`` in the ``views`` package. It -should already contain the following: +Open ``tutorial/views/default.py`` in the ``views`` package. It should already +contain the following: .. literalinclude:: src/basiclayout/tutorial/views/default.py :linenos: :language: py The important part here is that the ``@view_config`` decorator associates the -function it decorates (``my_view``) with a :term:`view configuration`, +function it decorates (``my_view``) with a :term:`view configuration`, consisting of: * a ``route_name`` (``home``) @@ -172,12 +171,11 @@ Note that ``my_view()`` accepts a single argument named ``request``. This is the standard call signature for a Pyramid :term:`view callable`. Remember in our ``__init__.py`` when we executed the -:meth:`pyramid.config.Configurator.scan` method ``config.scan()``? The -purpose of calling the scan method was to find and process this -``@view_config`` decorator in order to create a view configuration within our -application. Without being processed by ``scan``, the decorator effectively -does nothing. ``@view_config`` is inert without being detected via a -:term:`scan`. +:meth:`pyramid.config.Configurator.scan` method ``config.scan()``? The purpose +of calling the scan method was to find and process this ``@view_config`` +decorator in order to create a view configuration within our application. +Without being processed by ``scan``, the decorator effectively does nothing. +``@view_config`` is inert without being detected via a :term:`scan`. The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:`` clause to detect if there is a problem accessing the project @@ -189,12 +187,12 @@ to inform the user about possible actions to take to solve the problem. Content models with the ``models`` package ------------------------------------------ -In a SQLAlchemy-based application, a *model* object is an object composed by +In an SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` scaffold put the classes that implement our models. -First, open ``tutorial/models/meta.py``, which should already contain -the following: +First, open ``tutorial/models/meta.py``, which should already contain the +following: .. literalinclude:: src/basiclayout/tutorial/models/meta.py :linenos: @@ -213,10 +211,10 @@ Next we create a ``metadata`` object from the class :class:`sqlalchemy.schema.MetaData`, using ``NAMING_CONVENTION`` as the value for the ``naming_convention`` argument. -A ``MetaData`` object represents the table and other schema definitions for -a single database. We also need to create a declarative ``Base`` object to use -as a base class for our models. Our models will inherit from this ``Base``, -which will attach the tables to the ``metadata`` we created, and define our +A ``MetaData`` object represents the table and other schema definitions for a +single database. We also need to create a declarative ``Base`` object to use as +a base class for our models. Our models will inherit from this ``Base``, which +will attach the tables to the ``metadata`` we created, and define our application's database schema. .. literalinclude:: src/basiclayout/tutorial/models/meta.py @@ -225,17 +223,25 @@ application's database schema. :linenos: :language: py -We've defined the ``models`` as a packge to make it straightforward to -define models separately in different modules. To give a simple example of a -model class, we define one named ``MyModel`` in a ``mymodel.py``: +Next open ``tutorial/models/mymodel.py``, which should already contain the +following: + +.. literalinclude:: src/basiclayout/tutorial/models/mymodel.py + :linenos: + :language: py + +Notice we've defined the ``models`` as a package to make it straightforward for +defining models in separate modules. To give a simple example of a model class, +we have defined one named ``MyModel`` in ``mymodel.py``: .. literalinclude:: src/basiclayout/tutorial/models/mymodel.py :pyobject: MyModel + :lineno-match: :linenos: :language: py Our example model does not require an ``__init__`` method because SQLAlchemy -supplies for us a default constructor if one is not already present, which +supplies for us a default constructor, if one is not already present, which accepts keyword arguments of the same name as that of the mapped attributes. .. note:: Example usage of MyModel: @@ -259,14 +265,14 @@ Our ``models/__init__.py`` module defines the primary API we will use for configuring the database connections within our application, and it contains several functions we will cover below. -As we mentioned above, the purpose of the ``models.meta.metadata`` object is -to describe the schema of the database. This is done by defining models that -inherit from the ``Base`` attached to that ``metadata`` object. In Python, code -is only executed if it is imported, and so to attach the ``models`` table -defined in ``mymodel.py`` to the ``metadata``, we must import it. If we skip -this step, then later, when we run +As we mentioned above, the purpose of the ``models.meta.metadata`` object is to +describe the schema of the database. This is done by defining models that +inherit from the ``Base`` object attached to that ``metadata`` object. In +Python, code is only executed if it is imported, and so to attach the +``models`` table defined in ``mymodel.py`` to the ``metadata``, we must import +it. If we skip this step, then later, when we run :meth:`sqlalchemy.schema.MetaData.create_all`, the table will not be created -because the ``metadata`` does not know about it! +because the ``metadata`` object does not know about it! Another important reason to import all of the models is that, when defining relationships between models, they must all exist in order for SQLAlchemy to @@ -313,9 +319,9 @@ Finally, we define an ``includeme`` function, which is a hook for use with :meth:`pyramid.config.Configurator.include` to activate code in a Pyramid application add-on. It is the code that is executed above when we ran ``config.include('.models')`` in our application's ``main`` function. This -function will take the settings from the application, create an engine, -and define a ``request.dbsession`` property, which we can use to do work -on behalf of an incoming request to our application. +function will take the settings from the application, create an engine, and +define a ``request.dbsession`` property, which we can use to do work on behalf +of an incoming request to our application. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: includeme -- cgit v1.2.3 From 640d7779b69f49ab11d7e276a7548684524bc215 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 9 Apr 2016 13:36:11 -0700 Subject: - add intersphinx targets --- docs/tutorials/wiki2/basiclayout.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/tutorials/wiki2/basiclayout.rst') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 1310e0969..ce67bb9e3 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -1,3 +1,5 @@ +.. _wiki2_basic_layout: + ============ Basic Layout ============ -- cgit v1.2.3