如何将CherryPy应用程序构建到MVC架构中?

时间:2013-09-19 05:35:44

标签: python sqlalchemy cherrypy

我计划将我的结构与此类似:

appname/libs/user
            /football
            /tax

库用户将拥有User的模型,控制器将显示REST JSON API和视图。

我目前面临的问题可分为两个主要问题,主要源于使用Django一段时间。我是CherryPy和SqlAlchemy的新手。

  1. 如何在每个库中定义模块?我面临的问题是我要在每个模型中继承Base Declarative和Engine,并将其作为独立应用程序运行,以生成其模型。有没有一种机制可以插入库,数据库应该拉出所有模型并创建它? (Django做的事情。)

  2. 如何定义路线/ apis? (a urls.py)

1 个答案:

答案 0 :(得分:1)

如何在appname/db/__init__.py中定义声明性基础(sqlalchemy),并为每个lib导入appnameappname/libs/NAME/models.py的基础:

import appname.db

Base = appname.db.Base    

class MyUser(Base):
    ...

例如,要获取数据库会话,请使用作用域会话,如果您不想在{{appname/db/__init__.py中定义其他基本模型,则可能是db.py的基本内容(或仅appname/db/models.py 1}})

from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import engine_from_config


__all__ = ['session', 'ses']

ses = session = scoped_session(sessionmaker())

def load_engine(config):
    engine =  engine_from_config(config, prefix='')
    session.configure(bind=engine)

然后设置一个工具,在请求结束时从线程本地删除会话:

import cherrypy

from appname import db

def remove_db_session():
    db.session.remove()

cherrypy.tools.removedbs = cherrypy.Tool('on_end_request', remove_db_session)

从那时起,只需在应用程序的任何部分正常使用会话,例如:

from appname import db
from appname.libs.user import models

class User:
    exposed = True

    def GET(self, id):
        db.ses.query(models.User).filter_by(id=id)
        # and let the tool to remove the session
        # when the request finish

顺便启用removedbs工具,只需确保执行cherrypy.tools.removedbs = ....我通常将其放在appname/cptools/tool中的某个位置,然后执行配置字典或文件集{ {1}}为真

使用cherrypy意味着您将构建应用程序树,如果您想使用MethodDispatcher或DefaultDispatcher,则没有额外的魔法需要有一个构建完整树的中心位置。

在这种情况下,我建议您使用MethodDispatcher,可能还需要this post can give you a little more perspectivethis is from my blog emulating the github api without any base handler

有一种替代方法可以使用更多类似于RoutesDispatcher的django路线,但是你会从这些工具中失去很多功能。

为了向您展示MethodDispatcher的示例并构建您自己的对象树,从当前结构中您可以在tools.removedbs.on上创建一个构建函数并进行如下操作:

appname/builder.py

from appname.views import Main from appname.libs import user, football appmap = {'user': user, 'footbal': football} def build_app(*apps): root = Main() for app in apps: appmodule = appmap[app] appmodule.attach(root) return root

appname/libs/user/__init__.py

这只是构建应用程序的一种方法,还有一个cherrypy recipes的存储库非常有帮助。