Defining the Domain Model¶
The first change we’ll make to our stock paster-generated application will be
to define a domain model constructor representing a wiki page. We’ll
do this inside our
The source code for this tutorial stage can be browsed at http://github.com/Pylons/pyramid/tree/1.0-branch/docs/tutorials/wiki2/src/models/.
Making Edits to
There is nothing automagically special about the filename
models.py. A project may have many models throughout its
codebase in arbitrarily-named files. Files implementing models
model in their filenames (or they may live in a
Python subpackage of your application package named
but this is only by convention.
The first thing we want to do is remove the stock
MyModel class from the
models.py file. The
MyModel class is only a sample and
we’re not going to use it.
Then, we’ll add a
Page class. Because this is a SQLAlchemy
application, this class should inherit from an instance of
SQLAlchemy models are easier to use than directly-mapped ones.
Page class will have a class level attribute
equals the string
pages. This means that SQLAlchemy will store our wiki
data in a SQL table named
pages. Our Page class will also have
class-level attributes named
data (all instances
sqlalchemy.Column). These will map to columns in the
id attribute will be the primary key in the table. The
name attribute will be a text attribute, each value of which needs to be
unique within the column. The
data attribute is a text attribute that
will hold the body of each page.
We’ll also remove our
populate function. We’ll inline the
populate step into
initialize_sql, changing our
function to add a FrontPage object to our database at startup time.
We’re also going to use slightly different binding syntax. It will
will otherwise largely be the same as the
initialize_sql in the
Our DBSession assignment stays the same as the original generated
Looking at the Result of Our Edits to
The result of all of our edits to
models.py will end up looking
something like this:
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
import transaction from sqlalchemy import Column from sqlalchemy import Integer from sqlalchemy import Text 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 Page(Base): """ The SQLAlchemy declarative model class for a Page object. """ __tablename__ = 'pages' id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Text) def __init__(self, name, data): self.name = name self.data = data def initialize_sql(engine): DBSession.configure(bind=engine) Base.metadata.bind = engine Base.metadata.create_all(engine) try: session = DBSession() page = Page('FrontPage', 'initial data') session.add(page) transaction.commit() except IntegrityError: # already created pass
Viewing the Application in a Browser¶
We can’t. At this point, our system is in a “non-runnable” state; we’ll need to change view-related files in the next chapter to be able to start the application successfully. If you try to start the application, you’ll wind up with a Python traceback on your console that ends with this exception:
ImportError: cannot import name MyModel
This will also happen if you attempt to run the tests.