Basic Layout¶
The starter files generated by the pyramid_routesalchemy
template
are basic, but they provide a good orientation for the high-level
patterns common to most url dispatch -based Pyramid
projects.
The source code for this tutorial stage can be browsed at http://github.com/Pylons/pyramid/tree/1.0-branch/docs/tutorials/wiki2/src/basiclayout/.
App Startup with __init__.py
¶
A directory on disk can be turned into a Python 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 package marker and to contain
configuration code.
The generated development.ini
file is read by paster
which looks for
the application module in the use
variable of the app:tutorial
section. The entry point is defined in the Setuptools configuration of this
module, specifically in the setup.py
file. For this tutorial, the entry
point is defined as tutorial:main
and points to the following main
function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from pyramid.config import Configurator from sqlalchemy import engine_from_config from tutorial.models import initialize_sql def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ engine = engine_from_config(settings, 'sqlalchemy.') initialize_sql(engine) config = Configurator(settings=settings) config.add_static_view('static', 'tutorial:static') config.add_route('home', '/', view='tutorial.views.my_view', view_renderer='templates/mytemplate.pt') return config.make_wsgi_app()
- Lines 1-4. Imports to support later code.
- Line 9. Create a SQLAlchemy database engine from the
sqlalchemy.
prefixed settings in thedevelopment.ini
file’s[app:tutorial]
section. This will be a URI (something likesqlite://
). - Line 10. We initialize our SQL database using SQLAlchemy, passing it the engine
- Line 11. We construct a Configurator.
settings
is passed as a keyword argument with the dictionary values passed by PasteDeploy as thesettings
argument. This will be a dictionary of settings parsed by PasteDeploy, which contains deployment-related values such asreload_templates
,db_string
, etc. - Line 12. We call
pyramid.config.Configurator.add_static_view()
with the argumentsstatic
(the name), andtutorial:static
(the path). This registers a static resource view which will match any URL that starts with/static/
. This will serve up static resources for us from within thestatic
directory of ourtutorial
package, in this case, viahttp://localhost:6543/static/
and below. 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. - Lines 13-14. Register a route configuration via the
pyramid.config.Configurator.add_route()
method that will be used when the URL is/
. Since this route has apattern
equalling/
it is the “default” route. The argument namedview
with the valuetutorial.views.my_view
is the dotted name to a function we write (generated by thepyramid_routesalchemy
template) that is given arequest
object and which returns a response or a dictionary. You will usepyramid.config.Configurator.add_route()
statements in a URL dispatch based application to map URLs to code. This route also names aview_renderer
, which is a template which lives in thetemplates
subdirectory of the package. When thetutorial.views.my_view
view returns a dictionary, a renderer will use this template to create a response. - Line 15. We use the
pyramid.config.Configurator.make_wsgi_app()
method to return a WSGI application.
Content Models with models.py
¶
In a SQLAlchemy-based application, a model object is an object
composed by querying the SQL database which backs an application.
SQLAlchemy is an “object relational mapper” (an ORM). The
models.py
file is where the pyramid_routesalchemy
Paster
template put the classes that implement our models.
Here is the source for models.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import transaction from sqlalchemy import Column from sqlalchemy import Integer from sqlalchemy import Unicode from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker from zope.sqlalchemy import ZopeTransactionExtension DBSession = scoped_session(sessionmaker( extension=ZopeTransactionExtension())) Base = declarative_base() class MyModel(Base): __tablename__ = 'models' id = Column(Integer, primary_key=True) name = Column(Unicode(255), unique=True) value = Column(Integer) def __init__(self, name, value): self.name = name self.value = value def populate(): session = DBSession() model = MyModel(name=u'root',value=55) session.add(model) session.flush() transaction.commit() def initialize_sql(engine): DBSession.configure(bind=engine) Base.metadata.bind = engine Base.metadata.create_all(engine) try: populate() except IntegrityError: pass
- Lines 1-13. Imports to support later code.
- Line 15. We set up a SQLAlchemy “DBSession” object here. We specify that we’d like to use the “ZopeTransactionExtension”. This extension is an extension which allows us to use a transaction manager instead of controlling commits and aborts to database operations by hand.
- Line 16. We create a declarative
Base
object to use as a base class for our model. - Lines 18-26. A model class named
MyModel
. It has an__init__
that takes a two arguments (name
, andvalue
). It stores these values asself.name
andself.value
within the__init__
function itself. TheMyModel
class also has a__tablename__
attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. - Lines 28-33. A function named
populate
which adds a single model instance into our SQL storage and commits a transaction. - Lines 35-42. A function named
initialize_sql
which receives a SQL database engine and binds it to our SQLAlchemy DBSession object. It also calls thepopulate
function, to do initial database population.