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 | 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 the development.ini file’s [app:tutorial]
section. This will be a URI (something like sqlite://).
- 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 the settings argument. This will be a
dictionary of settings parsed by PasteDeploy, which contains
deployment-related values such as reload_templates,
db_string, etc.
- Line 12. We call
pyramid.config.Configurator.add_static_view() with the
arguments static (the name), and tutorial: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 the
static directory of our tutorial package, in this case,
via http://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 a pattern equalling
/ it is the “default” route. The argument named view with the
value tutorial.views.my_view is the dotted name to a function we
write (generated by the pyramid_routesalchemy template) that is given
a request object and which returns a response or a dictionary. You
will use pyramid.config.Configurator.add_route() statements
in a URL dispatch based application to map URLs to code. This
route also names a view_renderer, which is a template which lives in
the templates subdirectory of the package. When the
tutorial.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, and value).
It stores these values as self.name and self.value within
the __init__ function itself. The MyModel 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 the populate function, to do initial database population.