Pylons 1.0 AttributeError: 'module' object has no attribute 'metadata'
Python noob trying to learn Pylons. I'm using the QuickWiki tutorial (http://pylonshq.com/docs/en/1.0/tutorials/quickwiki_tutorial/) from the 1.0 documentation, but this alleged "1.0" doc seems to just be "0.9.7"; I suspect that this has something to do with the error I'm getting.
When I execute "paster setup-app development.ini", I get this:
(mydevenv)lucid@lucid-laptop:~/QuickWiki$ paster setup-app development.ini
Traceback (most recent call last):
... edited for brevity...
File "/home/lucid/mydevenv/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg/pkg_resources.py", line 1954, in load
File "/home/lucid/QuickWiki/quickwiki/config/middleware.py", line 11, in <module>
from quickwiki.config.environment import load_environment
File "/home/lucid/Qui开发者_如何学编程ckWiki/quickwiki/config/environment.py", line 12, in <module>
from quickwiki.model import init_model
File "/home/lucid/QuickWiki/quickwiki/model/__init__.py", line 27, in <module>
pages_table = sa.Table('pages', meta.metadata,
AttributeError: 'module' object has no attribute 'metadata'
(mydevenv)lucid@lucid-laptop:~/QuickWiki$
This is mistake in documentation http://pylonshq.com/docs/en/1.0/tutorials/quickwiki_tutorial/
Declare pages_table like this
from quickwiki.model.meta import Base
pages_table = sa.Table('pages', Base.metadata,
sa.Column('title', sa.types.Unicode(40), primary_key=True),
sa.Column('content', sa.types.UnicodeText(), default='')
)
No loger meta.metadata, use meta.Base.metadata and define you models using SqlAlchemy declarative base extension http://www.sqlalchemy.org/docs/05/ormtutorial.html#creating-table-class-and-mapper-all-at-once-declaratively
Your comment on estin answer asks whether this changes between SqlAlchemy 0.5 and 0.6.
It does not. It's the same. It is Pylons which have different defaults now. As estin says Pylons defaults to creating a declarative_base() so that you can use SqlAlchemy declaratively.
class MyRecord(Base):
__tablename__ = "myrecord"
id = Column(Integer, primary_key=True)
data = Column(Unicode, nullable=False)
This is instead of specifying first the tables using Table() constructs, then creating your classes and then using mapper() to map them together.
SqlAlchemy Declarative does this automatically. Quickwiki tells you to use the explicit non-declarative version of SqlAlchemy which is there are no reason for (declarative is more concise). Pylons used to expose the default metadata as model.meta.metadata but now it is created by declarative_base() and exposed in model.meta.Base.metadata.
Just in case anyone runs into the same issue, I'm including my model.init and websetup:
"""=========================__init__.py========================="""
"""The application's model objects"""
from quickwiki.model.meta import Session, Base
def init_model(engine):
"""Call me before using any of the tables or classes in the model"""
Session.configure(bind=engine)
import logging
import re
import sets
from docutils.core import publish_parts
from pylons import url
from quickwiki.lib.helpers import link_to
log = logging.getLogger(__name__)
# disable docutils security hazards:
# http://docutils.sourceforge.net/docs/howto/security.html
SAFE_DOCUTILS = dict(file_insertion_enabled=False, raw_enabled=False)
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)", re.UNICODE)
from sqlalchemy import orm
import sqlalchemy as sa
pages_table = sa.Table('pages', Base.metadata,
sa.Column('title', sa.types.Unicode(40), primary_key=True),
sa.Column('content', sa.types.UnicodeText(), default='')
)
class Page(object):
def __init__(self, title, content=None):
self.title = title
self.content = content
def get_wiki_content(self):
"""Convert reStructuredText content to HTML for display, and
create links for WikiWords
"""
content = publish_parts(self.content, writer_name='html',
settings_overrides=SAFE_DOCUTILS)['html_body']
titles = sets.Set(wikiwords.findall(content))
for title in titles:
title_url = url(controller='pages', action='show', title=title)
content = content.replace(title, link_to(title, title_url))
return content
def __unicode__(self):
return self.title
__str__ = __unicode__
orm.mapper(Page, pages_table)
"""=========================websetup.py========================="""
"""Setup the QuickWiki application"""
import logging
import pylons.test
from quickwiki.config.environment import load_environment
from quickwiki.model.meta import Session, Base
from quickwiki import model
log = logging.getLogger(__name__)
def setup_app(command, conf, vars):
"""Place any commands to setup quickwiki here"""
load_environment(conf.global_conf, conf.local_conf)
# Create the tables if they don't already exist
log.info("Creating tables...")
Base.metadata.create_all(bind=Session.bind)
log.info("Successfully set up.")
log.info("Adding front page data...")
page = model.Page(title=u'FrontPage',
content=u'**Welcome** to the QuickWiki front page!')
Session.add(page)
Session.commit()
log.info("Successfully set up.")
精彩评论